ale*_*use -2 ruby floating-point ruby-on-rails rounding
我已经看过了:为什么十进制数不能用二进制精确表示?而为什么是浮点数不准确?
我的问题是,当我使用 ruby 对浮点数进行舍入和格式化时,结果仍然与进行数学运算的结果不同。下面是一个例子:
编辑 2
[28] pry(main)> #####################################
[29] pry(main)> # test one
[30] pry(main)> #####################################
[31] pry(main)> foo = (6.0135 * (650000 / 1000))
=> 3908.7749999999996
[32] pry(main)> foo = '%.2f' % foo.round(2)
=> "3908.77"
[33] pry(main)> # should be 3908.78
[36] pry(main)> #####################################
[37] pry(main)> # test two
[38] pry(main)> #####################################
[39] pry(main)> foo = 650000 / 1000
=> 650
[40] pry(main)> foo = foo * 6.0135
=> 3908.7749999999996
[41] pry(main)> foo = '%.2f' % foo.round(2) # should be 3908.78
=> "3908.77"
[44] pry(main)> #####################################
[45] pry(main)> # test three
[46] pry(main)> #####################################
[47] pry(main)> foo = 650000 / 1000
=> 650
[48] pry(main)> foo = foo * 6.0135
=> 3908.7749999999996
[49] pry(main)> foo = foo.round(2) # should be 3908.78
=> 3908.77
[52] pry(main)> #####################################
[53] pry(main)> # test four - The result of test four is expected
[54] pry(main)> #####################################
[55] pry(main)> foo = 650000 / 1000
=> 650
[56] pry(main)> foo = foo * 6.0135
=> 3908.7749999999996
[57] pry(main)> foo = '%.2f' % foo
=> "3908.77"
[58] pry(main)> #####################################
[59] pry(main)> # test five
[60] pry(main)> #####################################
[61] pry(main)> foo = 650000 / 1000
=> 650
[62] pry(main)> foo = foo * 6.0135
=> 3908.7749999999996
[63] pry(main)> foo = foo.round(5)
=> 3908.775
Run Code Online (Sandbox Code Playgroud)
测试 1:这是我在库中使用的正常公式,它给了我这个问题。
测试 2:我的想法是,在一项作业中同时进行两项操作可能会导致一些问题
测试 3:因为'%.2f' %众所周知会导致一些舍入问题,它会截断事物,也许这就是问题所在。
测试 4: 既然'%.2f' %不是问题,也许.round(2)是导致问题的原因。
编辑 2: 测试 5:如果我扩展该轮正在查看的数字,我会得到一个我可以使用的数字(即再次轮(2)该数字)。但这似乎是一个奇怪的解决方案,适用于有限的情况,而不适用于一般情况
我真的不在乎浮点数不准确。我的问题是如何正确舍入这个数字,以便得到正确的答案(如果您手动执行操作,您会得到的答案)。
此外,一般来说,是否有最佳实践来修正剂量点误差?我知道使用两个整数来表示浮点数,但这似乎很麻烦。
谢谢你。
编辑 1
如果您使用.round(5)而不是.round(2)在将其与答案应该是什么进行比较时,您会得到更合理的答案。增加回合内的数量有什么缺点吗?
round正在按预期工作。你得到错误的结果,因为你的输入已经有缺陷。浮点数6.0135实际上是:
6.01349999999999962341235004714690148830413818359375
Run Code Online (Sandbox Code Playgroud)
乘以这个数字650会使错误变得更糟。您得到的结果3908.77比 to更接近3908.78:
foo = 6.0135 * 650
#=> 3908.7749999999996
(foo - 3908.77).abs
#=> 0.004999999999654392
(foo - 3908.78).abs
#=> 0.005000000000563887
Run Code Online (Sandbox Code Playgroud)
要获得正确的结果,您可以使用以下方法:
foo = (6.0135 * 10000).round * 0.065
#=> 3908.775
foo.round(2)
#=> 3908.78
Run Code Online (Sandbox Code Playgroud)
或者您可以首先使用BigDecimal来避免浮点错误:
require 'bigdecimal'
foo = BigDecimal('6.0135') * 650
foo.to_s('F')
#=> "3908.775"
foo.round(2).to_s('F')
#=> "3908.78"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3537 次 |
| 最近记录: |