谁能解释为什么19.99 * 100是1998年的红宝石?

时间:2014-01-28 14:07:53

标签: floating-point

使用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个计算,逻辑肯定是相同的吗?

4 个答案:

答案 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