简单的方法去除Elixir中不必要的浮子精度?

时间:2017-04-22 19:51:36

标签: elixir

我有Elixir计算返回像这样的浮点数:

0.15300000000000002
5.140000000000005
0.0033000000000000004

但我只想显示:

0.153
5.14
0.0033

我熟悉使用......

:erlang.float_to_binary

...指定小数精度&舍入选项。问题是我不确切知道在手边设置精度的小数位。

有简单的方法吗?

2 个答案:

答案 0 :(得分:4)

由于浮点错误的性质,我不认为在没有选择精度的情况下有一般的方法。

:compact的{​​{1}}选项可以提供帮助:

float_to_binary

它将尾随零修剪到您指定的精度。

答案 1 :(得分:0)

1)一种可能性是以慢慢增加的精度对数字进行舍入,直到您在指定的容差范围内。例如

defmodule Foo do                                       
  def foo(num, tolerance, precision) do
    x = Float.round(num, precision)
    if num + tolerance > x and x > num - tolerance do
      x
    else
      foo(num, tolerance, precision + 1)
    end
  end
end
num = 0.15300000000000002
tolerance = 0.00000000001
Foo.foo(num, tolerance, 0) == 0.153

2)一种可能性是在进行计算之前将所有数字移到整数,然后将它们移回浮点数。 Elixir使用bignum arithmetic因此它不应该有任何问题。例如,下面给出了一个不精确的结果,最后有很多9。

iex(1)> 234.987 * 4085.984
960153.1222079999

但是,这个更准确。只需选择一些足够大的金额来转移。

iex(2)> (234.987 * 1_000_000) * (4085.984 * 1_000_000) / 1_000_000_000_000
960153.122208

为了更进一步,在我构建的许多系统中,我们只是因为精度问题而暂时停止使用浮动。例如,在存储和处理美元等货币时,请使用amount_cents而不是金额或100,而不是1.0。