我需要用坐标进行一些计算并遇到 这(至少对我而言)奇怪的行为。 有人可以解释为什么会这样吗?
$ long
=> 49.0126760222489
$ long % long.floor
=> 0.012676022248896857
我期待最后一行评估到句点之后的数字,从long
开始,但是在结尾处还有一个6857
。
为什么要添加数字?
信息来自哪里?
答案 0 :(得分:3)
它似乎与Ruby本身无关,但是:
浮点数通常会受到这种类型的舍入错误的影响,因为它们仅限于x个字节,并且通常不能完美地存储十进制数。
从上面的文档中,我们还可以获得一些解决本机浮动行为的选项。上述文档可视为官方文档,因为它由ruby-doc.org提供。
答案 1 :(得分:2)
我想我们只是看到浮动的诅咒。请参阅0.0126760222489 % 1.0
和1.0126760222489 % 1.0
。你认为结果应该是相同的,但是没有 - IEEE754浮点/双打不能保证完美的结果,默认情况下这些用于Ruby存储浮点值。
甚至有点显示in the docs
6543.21.modulo(137) #=> 104.21
6543.21.modulo(137.24) #=> 92.9299999999996
你可以看到第二个结果有一个小错误。实际上,在Ruby 2.3.1上我运行了第一行并得到了:
pry(main)> 6543.21.modulo(137)
=> 104.21000000000004
它不一定与modulo有关,也不一定总是可见:
[30] pry(main)> 10.0126760222489 - 0.0
=> 10.0126760222489
[31] pry(main)> 10.0126760222489 - 1.0
=> 9.0126760222489
[32] pry(main)> 10.0126760222489 - 2.0
=> 8.0126760222489
[33] pry(main)> 10.0126760222489 - 3.0
=> 7.0126760222489
[34] pry(main)> 10.0126760222489 - 4.0
=> 6.0126760222489
[35] pry(main)> 10.0126760222489 - 5.0
=> 5.0126760222489
[36] pry(main)> 10.0126760222489 - 6.0
=> 4.0126760222489
[37] pry(main)> 10.0126760222489 - 7.0
=> 3.0126760222489004
使用标准浮动的每个软件都需要考虑这些小错误。如果由于某种原因无法处理,那么你可以使用bigdecimal
(应该已经包含在你的Ruby中),定点或类似的数字库
require 'bigdecimal'
BigDecimal('6543.21').modulo(137).to_s
=> "0.10421E3"
BigDecimal('6543.21').modulo(137).to_f
=> 104.21
请记住' bigdecimal'可能会更慢,可能会占用更多内存。