【发布时间】:2012-09-09 10:55:36
【问题描述】:
我了解到建议使用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 中的错误吗?
【问题讨论】:
-
不幸的是,这就是二进制浮点的工作方式。如果你想要这样严格的行为,你的“昂贵的话语权”就是这样做的。
-
您正在寻找可预测的 binary 近似值,将 binary 近似值的 decimal 四舍五入到 decimal 中途案例。这就是疯狂!
标签: ruby floating-point floating-accuracy ruby-1.9.3