Ruby on rails 十进制数的Ruby舍入和格式化
我已经看完了:而且 我的问题是,当我使用ruby对浮点数进行取整和格式化时,结果仍然与手工计算的结果不同。下面是一个例子: 编辑2Ruby on rails 十进制数的Ruby舍入和格式化,ruby-on-rails,ruby,floating-point,rounding,Ruby On Rails,Ruby,Floating Point,Rounding,我已经看完了:而且 我的问题是,当我使用ruby对浮点数进行取整和格式化时,结果仍然与手工计算的结果不同。下面是一个例子: 编辑2 [28] pry(main)> ##################################### [29] pry(main)> # test one [30] pry(main)> ##################################### [31] pry(main)> foo = (6.0135 * (6500
[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
测试1:这是我在我的库中使用的正常公式,它给了我这个问题
测试2:我的想法是,可能在一个作业中同时做两个操作会导致一些问题
测试3:既然大家都知道,“%.2f”%
会导致一些舍入问题,它会截断某些内容,那么这可能就是问题所在
测试4:既然'%.2f%
不是问题所在,可能是.round(2)
导致了问题
编辑2:
测试5:如果我展开该轮正在查看的数字,我会得到一个可以使用的数字(即,再次对该数字进行第(2)轮)。但这似乎是一个不可靠的解决方案,适用于有限的情况,而不是一般情况
我真的不在乎浮点是不准确的。我的问题是如何正确地将这个数字四舍五入,以便得到正确的答案(如果您手工操作,您将得到正确的答案)
此外,一般来说,是否有最佳的四舍五入做法来纠正给药点错误?我知道用两个整数来表示浮点数是很困难的,但这似乎很麻烦
多谢各位
编辑1
如果您使用
.round(5)
而不是.round(2)
将答案与应该的答案进行比较,您会得到更合理的答案。增加一轮中的数字有什么缺点吗?'%.2f%
-截断数字并无法正确进行四轮
.round(2)
-找不到足够的小数位,无法正确地返回到四舍五入。所以,如果你把数字放在大于2的范围内,四舍五入的问题就不存在了
编辑1
根据IEEE标准,有5种方法可对数字进行四舍五入:
在这种情况下,与其说我是如何舍入的,不如说是需要考虑小数点后的位数。通常,一个人需要担心精确度。由于此错误是由计算机造成的,因此我假设增加小数点后的数值会更好、更准确。我在Rails控制台上对其进行了测试,没有发现任何奇怪的行为:
>> foo = 650000 / 1000
=> 650
>> foo = foo * 6.0135
=> 3908.7749999999996
>> foo.round(2)
=> 3908.77
>> foo.round(3)
=> 3908.775
>> foo.round(5)
=> 3908.775
>> afoo = '%.2f' % foo
=> "3908.77"
>> afoo = '%.5f' % foo
=> "3908.77500"
3908.7749999996小于3908.775,如果使用,将向下舍入为3908.77。舍入(2)。
.3908.775中预期的四舍五入结果,也可以使用谷歌计算器进行复制。你为什么认为这是不正确的?我很想了解这一点。
round
按预期工作。你得到了错误的结果,因为你的输入已经有缺陷了。浮点数6.0135
实际上是:
6.01349999999999962341235004714690148830413818359375
将此数字乘以650
会使错误更严重。您得到的结果更接近于3908.77
,而不是3908.78
:
foo = 6.0135 * 650
#=> 3908.7749999999996
(foo - 3908.77).abs
#=> 0.004999999999654392
(foo - 3908.78).abs
#=> 0.005000000000563887
要获得正确的结果,您可以使用以下方法:
foo = (6.0135 * 10000).round * 0.065
#=> 3908.775
foo.round(2)
#=> 3908.78
或者,您可以首先使用BigDecimal
来避免浮点错误:
require 'bigdecimal'
foo = BigDecimal('6.0135') * 650
foo.to_s('F')
#=> "3908.775"
foo.round(2).to_s('F')
#=> "3908.78"
为什么投反对票?这一轮是正确的。3908.77499999.. 将始终为3908.77,因为它确实小于3908.775。你总是对总值进行四舍五入,而不是从最后一个数字开始四舍五入,然后再继续……除了实际答案应该是3908.78这一事实之外。如果你使用
.round(5)
你会得到3908.78更清楚地说,否决票不是我的,但诚实地说,在.round(2)中应该是3908.77。和.round(5)应该为您提供3908.775,并且在我的rails控制台中也是如此。请发布您遇到问题的代码。不是代码的图片,而是代码。我想你需要引用IEEE浮点标准来证明这些陈述的合理性,然后才能作为答案。是的@muistooshort和lukasz,我实际上对如何“解决”这个问题有了第二个想法。这给了我这个具体案例的答案。这样做还有其他问题吗?谢谢。除了一些性能上的影响之外,是否还有一些重大的倒退?我打算对每个请求进行25次这种计算,这种更改会对请求的性能产生很大影响吗?@alex_milhouse Rails中的请求-响应周期并不是那么轻量级的。如果25次计算会对它产生显著影响,我会感到惊讶。太好了。谢谢,这正是我需要的。