我很好奇爲什麼Ruby渲染精度爲2的小數點不一致。number_to_currency舍入精度錯誤
例如:
helper.number_to_currency 9.995
=> 「$ 9.99加入」
同時
helper.number_to_currency 10.995
=> 「$ 11.00」 ...它應該是 「$ 10.99」?
我很好奇爲什麼Ruby渲染精度爲2的小數點不一致。number_to_currency舍入精度錯誤
例如:
helper.number_to_currency 9.995
=> 「$ 9.99加入」
同時
helper.number_to_currency 10.995
=> 「$ 11.00」 ...它應該是 「$ 10.99」?
這是一個浮點精度錯誤。我可能會提交一個補丁來解決這個問題,因爲我在我的網站上也使用了number_to_currency。
這裏所發生的事情的詳細信息:
number_to_currency
最終只是打電話number_with_precision
得到正確格式化的數字。 number_with_precision
立即將數字轉換爲浮點數。實質上,它歸結爲Rails代碼中的這一行:
# File actionpack/lib/action_view/helpers/number_helper.rb, line 280
rounded_number = BigDecimal.new((number * (10 ** precision)).to_s).round.to_f/10 ** precision
在提供的數字轉換爲BigDecimal之前,您提供的數字乘以100。看看這個簡單的irb會話:
irb(main):001:0> 9.995 * 100
=> 999.4999999999999
這個數字顯然會舍入到999,然後它會被除以100給你9.99。
目前唯一可以考慮的解決方法是在傳遞數字之前自己做四捨五入。
我提交了一個可以在此觀看的補丁: https://rails.lighthouseapp.com/projects/8994/tickets/6182-another-rounding-problem-in-number_with_precision – dontangg 2010-12-16 20:07:22
看起來就像是使用「Round half to odd」規則。因此,「1.5」向下取整爲最接近的奇數(1),2.5取整爲最接近的奇數(3)。
對於一組隨機分佈的數字進行四捨五入,這種舍入形式將巧妙地產生未接數的總和與四捨五入的數之和中的最小差值。
這可能是一個浮點精度問題。 – You 2010-11-22 02:55:54