Ruby Ruby 怎么会有这么诡异的问题?

ibachue · 2013年03月10日 · 最后由 ashchan 回复于 2013年03月11日 · 2202 次阅读

Hi all,

ruby -e 'p 310399688698392600.0.to_i' 结果怎么会得到 310399688698392576 这个结果的呢? 1.8 和 1.9 都是如此,哪位大牛能帮忙解释下?谢了

是浮点数实现自身的问题吧

#1 楼 @ShiningRay 我觉得如果这个问题出在编译型语言身上我还能理解,出现在解释型语言身上就不能理解了,Ruby 有很多机会可以纠正结果使之完全正确的

#2 楼 @iBachue JavaScript 结果 var f=310399688698392600.0 undefined f.toFixed() "310399688698392576"

#3 楼 @ShiningRay 好吧,这个问题从来就没有什么语言重视过嘛?

我猜是这样,浮点数是底层硬件直接支持运算的类型,默认用精确数的话效率就不一样了。

#6 楼 @Rei 效率不重要嘛

#6 楼 @Rei 连结果值都是错的,效率有何用?

浮点类型都不靠谱,处理数字有小数点的直接就推荐用 BigDecimal 了

#8 楼 @iBachue 浮点数就是个精度问题,超过那个精度后面的尾数都有可能出错,肯定是要取舍的 这些浮点数实现都是通过那个 IEEE 754 的标准,在硬件层面实现的,所以跟语言都没关系。 所以,还是用 BigDecimal 吧

超过 12 个数,就用 BigDecimal 了

#7 楼 @iBachue CPU 专门有个浮点数运算器,GPU 的浮点数运算也是性能重要指标,如果这两个原件直接被废了那肯定有什么问题,Ruby 就算不上通用语言了,成为一个 DSL。

估计 310399688698392600.0 在存储的时候,应该是以 3.10399688698392600 乘 10 的 17 次方存储的。 问题就出在前面的浮点上面了。当它还原的时候,就把后面的精度丢了。

个人觉得,这个问题我们解决不了,只能了解它并合理得利用或避开它。用浮点数的时候应该要考虑到这方面的问题的。有的问题不适合用浮点数解决。

#8 楼 @iBachue 这话是对的,首先要满足的是正确性~

二进制 不能完整的描述所有的小数,就像十进制不能完整的描述 1/3 一样。 这和语言没有关系,C++ C# 都有这个问题。 这和浮点数的存储机制有关。 如果需要需要精度处理 最好 用 BigDecimal。

#8 楼 @iBachue 结果并不错,只是精度没满足你的要求而已。310399688698392600.0 和 310399688698392600.000000000000 是一样的吗?不一样吗?:)

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