2017-04-21 14 views
6

Jaki jest najbardziej bezpośredni, skuteczny sposób na wykonanie tego w eliksiru?Jak sformatować numer do dokładności w eliksiru?

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 

Odpowiedz

4

Nie ma nic takiego w bibliotece standardowej eliksir jako o ile wiem, ale można użyć :io_lib.format/2 z Erlang wydrukować pacy z określonej liczby cyfr po kropce:

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'] 

Zwrócona wartość jest iolist, które mogą być przekształcone w binarnym za pomocą IO.iodata_to_binary/1 jeśli jest to wymagane (wiele funkcji, które mają binarny może przyjąć iolist bezpośrednio, jak również, na przykład IO.puts/1)

iex(5)> :io_lib.format("~.6f", [123.0]) |> IO.iodata_to_binary 
"123.000000" 

~.0f nie działa, ale za to można po prostu zadzwonić trunc/1:

iex(6)> trunc(123.123) 
123 
1

Użyłem do tego pakietu decimal poprzednio

iex(6)> 123 |> Decimal.new() |> Decimal.round(3) |> Decimal.to_string() 
"123.000" 

W moim przypadku dane zostały już Format dziesiętny po zapytaniu z bazy danych.

14

Po prostu chcę dostarczyć alternatywę dla doskonałej odpowiedzi Dogberta.

Jest również możliwe zastosowanie: erlang.float_to_binary/2

ex.

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

To jest o wiele lepsze niż moja odpowiedź! Sprawdziłem 'Float.to_string', ale nie miałem żadnych opcji i zapomniałem sprawdzić funkcje' float_to_ * 'w Erlang. – Dogbert

1

Tak z ciekawości, to w jaki sposób zaimplementować w czystą Elixir:

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" 
2

Odpowiedzi te są najczęściej nieparzysta. Po pierwsze, nie powiedziała nic o konwersji na ciąg. Po drugie, nie ma potrzeby wskakiwać na ziemię Erlang!

w celu:

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> 

Gdy masz numer w Decimal, możesz robić, co chcesz, na przykład konwertować do pacy, konwersja na łańcuch, itp

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 

Tak na marginesie, polecam działa jedynie w Decimal aż skończysz manipulacji danych, na przykład używanie Decimal.mult(num1, num2), Decimal.div(num1, num2), itp. Decimal skały!