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

我了解到建议使用BigDecimal而不是Float ,但这个要么是bug,要么突出了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舍入模式是“Round to nearest,ties to even”,这与“Round to nearest to ties from zero”不同,这是您从学校可能熟悉的。