有沒有人對此有任何建議?使用ruby printf格式說明符的奇數舍入問題
當我們運行:
printf("%.0f", 40.5)
在Windows中返回的是 「41」,但我們的生產Ubuntu的服務器我們得到的 「40」
有沒有人對此有任何建議?使用ruby printf格式說明符的奇數舍入問題
當我們運行:
printf("%.0f", 40.5)
在Windows中返回的是 「41」,但我們的生產Ubuntu的服務器我們得到的 「40」
看起來像一個簡單的案例binary floating point imprecision。在一臺機器上,你可以得到40.499999999到40;在另一臺機器上,你得到40.500000000001,其中四捨五入41.
如果你需要確切的數字,那麼你不應該使用二進制浮點數。您可以使用定點十進制或十進制浮點。
編輯:你正在使用BigDecimal,你說。爲什麼不通過使用#round
然後#to_i
來避免任何轉換浮動? (或者#floor
或#ceil
代替#round
......它沒有清除您的目標是什麼。)
b = BigDecimal.new("40.5")
print b.round.to_i # => 41
有關使用.round
,而不是如何呢? Rails甚至增強了它,以便您可以指定精度(see API doc)。
儘管40.5.round(0)給出了41.0,但是我們首先想要做到這一點,這非常煩人。我從API文檔看到.round現在接受nil,只剩下41和0之後。我敢肯定,在我們正在使用的Rails版本中,round(nil)拋出錯誤。爲了解決它,我們首先圍繞它(0),然後應用字符串格式。謝謝。 – tsdbrown 2009-12-01 15:37:41
我不明白tsdbrown的評論。浮輪#輪不會有任何爭論。 BigDecimal#round指定小數位數和ruby-doc.org作爲合法參數不顯示nil。 BigDecimal也不區分41.0和41. – ScottJ 2009-12-01 23:15:35
使用%0.0克代替
ScottJ的答案並不能解釋你的問題 - 40.5是精確表示二進制文件。可能發生的情況是:Windows'printf'減半,「而Ubuntu的printf」則減半。「
我保持這個例子非常簡單,但是這個數字實際上來自數據庫中的BigDecimal字段。我相信它提到的浮點問題只是不確定爲什麼它被視爲浮點數。您仍然遇到以下問題: 「%.0f」%BigDecimal(「40.5」)和「%.0d」%BigDecimal(「40.5」) – tsdbrown 2009-12-01 15:47:06
這是因爲這裏的BigDecimals正在轉換爲浮動(通過#to_f)在進行格式化操作之前。 – ScottJ 2009-12-01 23:18:37
如果不清楚,我編輯了我的上面的答案,以專門解決BigDecimal的問題。 – ScottJ 2009-12-01 23:21:48