2009-11-30 38 views

回答

0

看起來像一個簡單的案例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 
+0

我保持這個例子非常簡單,但是這個數字實際上來自數據庫中的BigDecimal字段。我相信它提到的浮點問題只是不確定爲什麼它被視爲浮點數。您仍然遇到以下問題: 「%.0f」%BigDecimal(「40.5」)和「%.0d」%BigDecimal(「40.5」) – tsdbrown 2009-12-01 15:47:06

+0

這是因爲這裏的BigDecimals正在轉換爲浮動(通過#to_f)在進行格式化操作之前。 – ScottJ 2009-12-01 23:18:37

+0

如果不清楚,我編輯了我的上面的答案,以專門解決BigDecimal的問題。 – ScottJ 2009-12-01 23:21:48

2

有關使用.round,而不是如何呢? Rails甚至增強了它,以便您可以指定精度(see API doc)。

+0

儘管40.5.round(0)給出了41.0,但是我們首先想要做到這一點,這非常煩人。我從API文檔看到.round現在接受nil,只剩下41和0之後。我敢肯定,在我們正在使用的Rails版本中,round(nil)拋出錯誤。爲了解決它,我們首先圍繞它(0),然後應用字符串格式。謝謝。 – tsdbrown 2009-12-01 15:37:41

+0

我不明白tsdbrown的評論。浮輪#輪不會有任何爭論。 BigDecimal#round指定小數位數和ruby-doc.org作爲合法參數不顯示nil。 BigDecimal也不區分41.0和41. – ScottJ 2009-12-01 23:15:35

1

使用%0.0克代替

1

ScottJ的答案並不能解釋你的問題 - 40.5是精確表示二進制文件。可能發生的情況是:Windows'printf'減半,「而Ubuntu的printf」則減半。「