如何在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 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" 
+1

这比我的回答更好!我检查了'Float.to_string',但它没有任何选项,我忘记检查Erlang中的'float_to_ *'函数。 – Dogbert

只是出于好奇,这就是我将如何实现在纯药剂:

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岩石!