在不使用 Elixir 中的科学形式的情况下删除小数尾随零

Remove Decimal trailing zeros without using scientific form in Elixir

我想从小数部分删除尾随零并保持整数部分为中性形式(因此不要将其从 100 更改为 1e2。使用 Decimal正确删除了尾随零,但它也切换为科学记数法。

iex(30)> d = Decimal.new("1.00000")
#Decimal<1.00000>
iex(31)> Decimal.reduce(d)
#Decimal<1>
iex(32)> d = Decimal.new("100.00000")
#Decimal<100.00000>
iex(33)> Decimal.reduce(d)
#Decimal<1E+2>
"100.00000" 
|> Decimal.new() 
|> Decimal.round(0) 
|> Decimal.to_integer 
|> Decimal.new()

等于

#Decimal<100>

我想这就是你应该走的路。然而,小数的表示并不重要,我相信它在存储时仍然是相同的格式。除非这与可读性有关?

经过进一步调查后,我发现表现形式不一样。 考虑以下因素。

iex(35)> x = "100.0000000" |> Decimal.new() |> Decimal.round(0) |> Decimal.to_integer |> Decimal.new()
#Decimal<100>

x 在内部表示为 %Decimal{sign: 1, coef: 100, exp: 0}。这是科学计数法100 * 10^0(即100 * 1)。

但如果我们只使用 reduce/1 函数,它的表示方式会有所不同:

iex(50)> y = Decimal.new("100.0000000") |> Decimal.reduce()                                                
#Decimal<1E+2>

y表示为%Decimal{sign: 1, coef: 1, exp: 2}。这是科学计数法1 * 10^2(即1 * 100)。

这些值完全相同,但表示方式不同,并且 == 也不相等。使用 Decimal.equal?/2.

它们是相同的
iex(64)> x == y
false
iex(65)> Decimal.equal?(x, y)
true

最后更新:如果这是关于文本形式的表示,你总是可以使用 to_string/2 函数并告诉它输出 "normal" 表示。

iex(68)> y |> Decimal.to_string(:normal)
"100"
iex(69)> x |> Decimal.to_string(:normal)
"100"

此处列出了所有选项:https://hexdocs.pm/decimal/Decimal.html#to_string/2

发件人:https://hexdocs.pm/elixir/Kernel.html#trunc/1

trunc(number)

规格

trunc(number()) :: integer()

Returns 数字的整数部分。

在守卫测试中允许。由编译器内联。

示例:

iex> trunc(5.4)
> 5

iex> trunc(-5.99)
> -5

iex> trunc(-5)
> -5