【问题标题】:In ruby, why is "100.7".to_f.modulo(1) = 0.700000000000003?在红宝石中,为什么“100.7”.to_f.modulo(1) = 0.700000000000003?
【发布时间】:2009-08-18 21:08:43
【问题描述】:

这对我来说很奇怪:

irb(main):012:0> "100.7".to_f.modulo(1)
=> 0.700000000000003

为什么最后是 3?

irb(main):019:0> "10.7".to_f.modulo(1)
=> 0.699999999999999

同样的事情......我们只得到这个值的余数除以一。应该是准确的。

【问题讨论】:

  • 几乎所有[floating-point] 问题的重复。例如,请参阅stackoverflow.com/questions/1089018/…
  • 这也是 ruby​​-talk 邮件列表或任何曾经存在的任何编程语言的讨论论坛上大约 100 个线程的副本。

标签: ruby floating-point modulo


【解决方案1】:
【解决方案2】:

这是典型的浮点舍入。您根本无法用浮点数的固定位数表示每个十进制数,因此某些值会四舍五入到可以表示的最接近的值。

因此,建议您不要比较浮点数是否相等。比较小于或大于,但从不完全相等。

http://en.wikipedia.org/wiki/Floating_point#Representable_numbers.2C_conversion_and_rounding

简单地说,“它应该是准确的”并不是这种情况。不要指望浮点小数。

【讨论】:

    【解决方案3】:

    欢迎来到浮点数学。有许多数字无法用标准浮点表示法表示,而且只是稍微偏离了一点。

    这很容易说明如下:

    (1..10).collect do |i|
      v = ((10**i).to_f + 0.7)
      puts "%13.1f = %.30f" % [ v, v.modulo(1) ]
    end
    

    结果在哪里:

             10.7 = 0.699999999999999289457264239900
            100.7 = 0.700000000000002842170943040401
           1000.7 = 0.700000000000045474735088646412
          10000.7 = 0.700000000000727595761418342590
         100000.7 = 0.699999999997089616954326629639
        1000000.7 = 0.699999999953433871269226074219
       10000000.7 = 0.699999999254941940307617187500
      100000000.7 = 0.700000002980232238769531250000
     1000000000.7 = 0.700000047683715820312500000000
    10000000000.7 = 0.700000762939453125000000000000
    

    请注意,数字越大,小数点后的精度越低。这是因为有一个固定数量的精度可用于表示整个数字。

    【讨论】:

      【解决方案4】:

      浮点数不精确。简短的版本是不可能在有限数量的位中存储无限数量的值。

      较长的版本是What Every Computer Scientist Should Know About Floating-Point Arithmetic

      【讨论】:

        【解决方案5】:

        这是因为不可能精确地表示所有浮点数。

        【讨论】:

          猜你喜欢
          • 2012-03-20
          • 2012-03-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-10-17
          • 1970-01-01
          • 2019-06-22
          相关资源
          最近更新 更多