我有一个用 Ruby 编写的简单程序。代码是:
#!/usr/bin/ruby
# odd behavior here
j = 1.11
while j < 2
print "iteration #{j}\n"
j += 0.01
end
我在装有 Mountain Lion 的 MacBook Air 上运行它。我的 Ruby 版本是:
ruby 1.9.3p327 (2012-11-10 revision 37606) [x86_64-darwin11.4.2]
我看到的奇怪行为是:
iteration 1.1
iteration 1.11
iteration 1.12
iteration 1.1300000000000001
iteration 1.1400000000000001
现在,如果我将 j 更改为 1.13,我会得到以下结果(为简洁起见,我删除了一些输出):
iteration 1.13
iteration 1.14
iteration 1.15
...
iteration 1.36
iteration 1.37
iteration 1.3800000000000001
iteration 1.3900000000000001
iteration 1.4000000000000001
iteration 1.4100000000000001
iteration 1.4200000000000002
这里发生了什么?最初,我认为这可能与值如何存储在 j 中有关,并且 1.13 具有一些特殊属性。然而,从 1.13 开始的 j 颠覆了这一理论。真正让我感动的是,这似乎并不一致。换句话说,奇怪的“0000000000”在哪里发挥作用似乎有些武断(尽管我确定不是)。
更糟糕的是,如果我将“j < 2”更改为“j < 5”,我会得到更奇怪的行为。
...
iteration 4.85999999999994
iteration 4.86999999999994
iteration 4.8799999999999395
iteration 4.889999999999939
iteration 4.899999999999939
iteration 4.909999999999939
iteration 4.919999999999939
iteration 4.929999999999938
iteration 4.939999999999938
iteration 4.949999999999938
iteration 4.959999999999938
iteration 4.969999999999938
iteration 4.979999999999937
iteration 4.989999999999937
iteration 4.999999999999937
我试过用谷歌搜索,但老实说,我不确定从哪里开始。我发现了一些线程,人们看到了 to_d 的奇怪行为,但没有什么能具体回答我的问题。此外,我对 Ruby 的了解还不够,无法完全理解发生了什么。这一定是精确度和 Ruby 如何存储数字的问题,但我不知道该去哪里找。
非常感谢任何朝着正确方向的推动!谢谢!