新手问题 0.step (1.0, 0.1) { |num| puts num}结果困惑

eclipse2008 · 2012年11月21日 · 最后由 sevk 回复于 2012年12月07日 · 4002 次阅读

ruby 版本 ruby 1.9.2p290 (2011-07-09) [i386-mingw32]

0.step(1.0, 0.1) { |num| puts num}

0.0 0.1 0.2 0.30000000000000004 0.4 0.5 0.6000000000000001 0.7000000000000001 0.8 0.9 1.0

0.30000000000000004 0.6000000000000001 0.7000000000000001 这是为何?

1.9.3p194 有同样问题

据说是浮点数精度之类的东西

经过 twitter 上的 @mwenyuan 指导,搜到这样一篇文章做参考

http://mzhou.me/article/45001/

#2 楼 @blacktulip 感谢你的回答,我上不了 Twitter,你提供的文章我看了一下 “0.1+0.2=0.30000000000000004”? 我试了下 js 和 ruby 有个这个问题 lua 和 python 没有这个问题,0.1+0.2=0.3 计算正确

翻到解决方法了:

>> require 'bigdecimal'
=> true
>> 0.step(BigDecimal('1.0'), BigDecimal('0.1')) { |num| puts num.to_f}
0.0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1.0
=> 0

多数 CPU 是以 IEEE754 来实作浮点数算数的(据此),这种规格是以二进位来表示小数,会因为除不尽而产生误差,所以叫 floating number。只要是直接通过 CPU 的 Arithmetic Unit 来计算小数,就会有同样的问题。

为了避免这个问题,会使用大数来计算,通常是开一个数组,每一格放一位数,用程序来实现四则运算,这也可以用来计算数值超过 CPU 整数范围的大数字。Ruby 的 BigDecimal 库就是来处理这个问题。


回完才发现 #2F 有解释 哈哈

用 round 就 ok 了

需要 登录 后方可回复, 如果你还没有账号请 注册新账号