如何在Elixir中将数字格式化为精确值?
使用长生不老药最直接、最有效的方法是什么如何在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
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
据我所知,Elixir的标准库中没有类似的内容,但您可以使用Erlang中的
: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
,如果需要,可以使用IO.iodata\u to_binary/1
将其转换为二进制文件(许多使用二进制文件的函数也可以直接接受iolist
,例如IO.put/1
):
~.0f
不起作用,但为此,您只需调用trunc/1
:
iex(5)> :io_lib.format("~.6f", [123.0]) |> IO.iodata_to_binary
"123.000000"
iex(6)> trunc(123.123)
123
我以前用过这个软件包
iex(6)> 123 |> Decimal.new() |> Decimal.round(3) |> Decimal.to_string()
"123.000"
在我的例子中,数据在从数据库查询后已经是十进制格式。只是想提供一个替代Dogbert优秀答案的方法 也可以使用:erlang.float_to_binary/2 前
出于好奇,这就是我在纯长生不老药中的实现方式:
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"
defmmodule NumFmt do
def格式(值、位置、圆?\\true)
def格式(值,位置,u)当为_整数(值),
do:格式(整数到字符串(值),位置)
def格式(值、位置、圆?)何时为浮点数(值),
do:格式(浮点)
|>应用((如果是圆形,则do::圆形,否则::楼层),[value,pos])
|>Float.to_字符串,位置)
def格式(值,0,u)为二进制(值)时,
do:采用[i | |格式(i.0”,位置,圆形?)
[i,f]->[i,f
|>字符串pad_尾随(位置“0”)
|>String.slice(0..pos-1)]|>Enum.join(“.”)
结束
结束
结束
IO.inspect NumFmt.格式(123.101,6),标签:“123.101000”
#⇒123.101000: "123.101000"
IO.inspect NumFmt.格式(123,3),标签:“123.000”
#⇒ 123.000: "123.000"
IO.inspect NumFmt.格式(123.101,1),标签:“123.1”
#⇒ 123.1: "123.1"
IO.inspect NumFmt.格式(123.000,0),标签:“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
,例如使用Decimal.mult(num1,num2)
,Decimal.div(num1,num2)
,等等Decimal
Decimal已被弃用,现在已在Elixir中删除,因此,对于稍后查找此帖子的人,以下是从Elixir v1.6开始如何执行此操作:
123.176
|> Float.round(2)
|> Float.to_string
# => "123.18"
编辑:修正了打字错误这比我的答案好得多!我选中了
Float.to\u string
,但它没有任何选项,我忘了检查Erlang中的Float\u to*
函数。@Serafeim你确定吗?使用Elixir 1.8.1和Erlang/OTP 21对我来说效果非常好。对不起!我想在下面@Madasebrof的答案中添加我的编辑和评论,但我错把它添加到了你的答案中!真的很抱歉,我把答案还原成原来的样子了!非常感谢,Serafeim这是一个很好的答案,但请注意,您需要添加第三方库。Decimal.new()已被弃用。您应该使用Decimal.from_float()。请小心:这是2019年的正确答案。其他答案(有更多投票)实际上不起作用:/例如,当您有123.10时,此解决方案不起作用,它返回“123.1”
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
123.176
|> Float.round(2)
|> Float.to_string
# => "123.18"