如何在Elixir中对数字进行精确格式化?
问题描述:
什么是最直接的,&在Elixir中做到这一点的有效方法?如何在Elixir中对数字进行精确格式化?
Starting number: 123.101
Ending number: 123.101000 # Adding 3 digits to the precision of a float.
Starting number: 123
Ending number: 123.000 # Adding 3 digits to the precision of an integer.
Starting number: 123.101
Ending number: 123.1 # removing precision
Starting number: 123.000
Ending number: 123 # removing precision
答
没有在药剂的标准库这样的事,据我知道,但你可以使用从二郎:io_lib.format/2
点后打印与数字的具体数量浮动:
iex(1)> :io_lib.format("~.3f", [123.101])
['123.101']
iex(2)> :io_lib.format("~.6f", [123.101])
['123.101000']
iex(3)> :io_lib.format("~.3f", [123.0])
['123.000']
iex(4)> :io_lib.format("~.6f", [123.0])
['123.000000']
返回值是一个iolist
,其可根据需要(即采取二进制可以直接接受iolist
以及许多功能,例如IO.puts/1
)被转换为使用IO.iodata_to_binary/1
二进制:
iex(5)> :io_lib.format("~.6f", [123.0]) |> IO.iodata_to_binary
"123.000000"
~.0f
不工作,但对于您可以简单地调用trunc/1
:
iex(6)> trunc(123.123)
123
答
我用过的decimal软件包这一先前
iex(6)> 123 |> Decimal.new() |> Decimal.round(3) |> Decimal.to_string()
"123.000"
在我的情况下,数据已经在从数据库查询后的十进制格式。
答
只是想提供一个替代Dogbert的优秀答案。
也可以使用:erlang.float_to_binary/2
前。
iex(5)> :erlang.float_to_binary(123.101, [decimals: 6])
"123.101000"
iex(6)> :erlang.float_to_binary(123.0, [decimals: 3])
"123.000"
iex(7)> :erlang.float_to_binary(123.101, [decimals: 1])
"123.1"
iex(8)> :erlang.float_to_binary(123.000, [decimals: 0])
"123"
答
只是出于好奇,这就是我将如何实现在纯药剂:
defmodule NumFmt do
def format(value, pos, round? \\ true)
def format(value, pos, _) when is_integer(value),
do: format(Integer.to_string(value), pos)
def format(value, pos, round?) when is_float(value),
do: format(Float
|> apply((if round?, do: :round, else: :floor), [value, pos])
|> Float.to_string, pos)
def format(value, 0, _) when is_binary(value),
do: with [i | _] <- String.split(value, "."), do: i
def format(value, pos, round?) when is_binary(value) do
case String.split(value, ".") do
[i] -> format(i <> ".0", pos, round?)
[i, f] -> [i, f
|> String.pad_trailing(pos, "0")
|> String.slice(0..pos - 1)] |> Enum.join(".")
end
end
end
IO.inspect NumFmt.format(123.101, 6), label: "123.101000"
#⇒123.101000: "123.101000"
IO.inspect NumFmt.format(123, 3), label: "123.000"
#⇒ 123.000: "123.000"
IO.inspect NumFmt.format(123.101, 1), label: "123.1"
#⇒ 123.1: "123.1"
IO.inspect NumFmt.format(123.000, 0), label: "123"
#⇒ 123: "123"
答
这些答案大多是奇数。首先,她没有说任何关于转换为字符串的内容。其次,肯定不需要跳入二郎地!
为了:
Starting number: 123.101
Ending number: 123.101000 # Adding 3 digits to the precision of a float.
iex> 123.101 |> Decimal.new() |> Decimal.round(6)
#Decimal<123.101000>
Starting number: 123
Ending number: 123.000 # Adding 3 digits to the precision of an integer.
iex> 123 |> Decimal.new() |> Decimal.round(3)
#Decimal<123.000>
Starting number: 123.101
Ending number: 123.1 # removing precision
iex> 123.101 |> Decimal.new() |> Decimal.round(1)
#Decimal<123.1>
Starting number: 123.000
Ending number: 123 # removing precision
iex> 123.000 |> Decimal.new() |> Decimal.round(0)
#Decimal<123>
一旦你有一个Decimal
数量,你可以做你想做的,例如转换为浮动,转换为字符串,等等
iex> 123.101 |> Decimal.new() |> Decimal.round(6) |> Decimal.to_string()
"123.101000"
iex> 123.101 |> Decimal.new() |> Decimal.round(6) |> Decimal.to_float()
123.101
iex> 123.101 |> Decimal.new() |> Decimal.round(0) |> Decimal.to_integer()
123
顺便说一句,我建议只在Decimal
工作,直到你完成所有的数据操作,例如使用Decimal.mult(num1, num2)
,Decimal.div(num1, num2)
等Decimal
岩石!
这比我的回答更好!我检查了'Float.to_string',但它没有任何选项,我忘记检查Erlang中的'float_to_ *'函数。 – Dogbert