Gau*_*ege 1 ruby floating-point floating-accuracy ruby-1.9.3
我了解到建议使用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
Run Code Online (Sandbox Code Playgroud)
round(3) 工作良好.
1.0015.round(3)
=> 1.002 # => CORRECT
1.235.round(2)
=> 1.24 # => CORRECT
Run Code Online (Sandbox Code Playgroud)
要在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
Run Code Online (Sandbox Code Playgroud)
这似乎是一种奇怪且昂贵的解决方法.这可能是一个错误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,ties from zero"不同,这是您从学校可能熟悉的.
| 归档时间: |
|
| 查看次数: |
469 次 |
| 最近记录: |