使用ruby版本2.0.0p247或1.9.3p286
在irb控制台
9.99 * 100 = 999.0
和
29.99 * 100 = 2999.0
但是
19.99 * 100 = 1998.9999999999998
任何人都可以解释这里发生了什么吗?我知道它可能是ruby核心中的一个错误,但对于上述3个计算,逻辑肯定是相同的吗?
答案 0 :(得分:5)
直接来自红宝石Float documentation:
Float对象使用native来表示不精确的实数 架构的双精度浮点表示。
浮点具有不同的算术并且是不精确的数字。所以 你应该知道它的深奥系统。见如下:
http://docs.sun.com/source/806-3568/ncg_goldberg.html
http://wiki.github.com/rdp/ruby_tutorials_core/ruby-talk-faq#wiki-floats_imprecise http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems
Ruby Tutorials Core的示例
Example of odd behavior:
>> (2.0-1.1) == 0.9
=> false
答案 1 :(得分:5)
为了正确计算,请确保使用BigDecimal数据类型,这对财务内容尤为重要。
19.99.to_d * 100.0.to_d
答案 2 :(得分:1)
回答这个具体问题:
但上述3次计算的逻辑肯定是一样的吗?
是的。但是,存储的值不是您在控制台中作为Float
文字输入的十进制表示的直接副本。相反,它被转换为内部形式。要了解发生了什么,您需要查看用于存储您正在操作的值的内部二进制表示。然后你会发现它是100%一致的,但不是100%精确的。
答案 3 :(得分:0)
将Float
点数乘以Integer
19.99 * 100
真的是:
# => 1998.9999999999998
由于使用64位双精度浮点来存储数字,因此它是known issue of accuracy。但是你可以得到规范化的浮点数:
puts "%.1f" % (19.99 * 100)
# => 1999.0