Ruby Float#round 方法在 round(2) 中表现不正确



我了解到建议使用BigDecimal而不是Float,但这要么是一个错误,要么突出了Float的深奥本质。似乎Float#round(2)"1.015"、"1.025"和"1.035"有问题。

1.015.round(2)
 => 1.01    # => WRONG .. should be 1.02
1.025.round(2)
 => 1.02    # => WRONG .. should be 1.03
1.035.round(2)
 => 1.03    # => WRONG .. should be 1.04
1.045.round(2)
 => 1.05    # => CORRECT
1.016.round(2)
 => 1.02    # => CORRECT

round(3)工作正常。

1.0015.round(3)
 => 1.002  # => CORRECT
1.235.round(2)
 => 1.24   # => CORRECT 

为了在 Rails 应用程序中修补这个猴子,我做了这个:

config/initializers/float_mp.rb
require 'bigdecimal'
class Float
  def round(val=0)
     BigDecimal.new(self.to_s).round(val).to_f
  end
end

这似乎是一个奇怪且昂贵的解决方法。这可能是Float#round中的错误吗?

AFAICS ruby round() 工作正常。据推测,无论如何,它只是 libm 中 round() 函数的包装器。

所以原因是浮点文字不能完全用二进制表示。 例如,用小数点多印"1.015"给出"1.0149999999999999"; 因此,当四舍五入到两位十进制数字时,1.01 比 1.02 更接近真实值。您的其他示例也是如此。

另请记住,默认的IEEE 754舍入模式是"舍入到最近,并列到

偶数",这与"舍入到最近,并列远离零"不同,后者可能是您在学校熟悉的。

相关内容

  • 没有找到相关文章

最新更新