2010-08-09 92 views
6

給定以下代碼,我期望它返回「float = 32000.0001」。但是相反,它返回「float = 32000.0」。在Java中舍入Float.parseFloat

System.out.println("float = "+Float.parseFloat("32000.0001")); 

有什麼我可以做,以防止/控制四捨五入?我希望完整的價值沒有舍入返回。

回答

7

浮點數只有24位的精度,這不足以保存您的值中的位數。舍入不是由於解析,而是由於數字的大小。如果需要浮點,則必須使用double;如果需要任意精度,則必須使用BigDecimal。

1

如果小數位對您有用,我會強烈建議使用BigDecimal來代替。

因爲它是,它不是完全清楚,我(不檢查)問題是否是解析從字符串格式化返回一個字符串。

編輯:在這種情況下,我強烈懷疑這是四捨五入的解析......因爲float只有7個(保證)顯著數字,你要保持9

+0

我打破了單行成多行並運行它通過調試。問題似乎出現在解析中。看來Float.parseFloat四捨五入到「32000.0」 – Shane 2010-08-09 14:17:33

+0

@Shane:你仍然認爲調試器正在向你顯示確切的值,我懷疑。 – 2010-08-09 14:44:12

+0

更改爲BigDecimal修復了我的小數問題 – jeff 2012-05-08 14:44:44

0

如果你想避免四捨五入,使用BigDecimal。原始類型floatdouble速度更快,但它們不能表示許多常見的十進制值。

0

浮球和雙打是有限的。它們只能精確地將數字的小數部分表示爲基本兩部分的總和。小數部分可以完全表示爲一些系列的像的總和:

1/2 + 0/4 1/8 + + + 1/16 ...

不幸的是大量的通常使用的號碼,從來沒有得到充分代表,如:

1/3,1/7,1/9,5/11等

您必須考慮的數量可以準確地代表你擔心之前四捨五入。如果這種類型的準確性非常重要,那麼您需要查看非浮點型或非雙精度型解決方案。

有二進制小數庫,將準確執行此類計算。他們往往計算速度較慢,因爲沒有專門的硬件來加速他們的計算。而且,他們傾向於佔用更多的內存,因爲你本質上是存儲一個數字列表。

在您可以表示您希望的細節數量之後,然後舍入解決方案很簡單。賠率是你甚至不需要舍入解決方案;因爲在這種情況下你試圖調整的主要原因是浮動不能正確表示你的價值。

2

在編寫軟件時使用浮點時需要非常小心。
某些十進制數字沒有確切的基數2表示是一件需要牢記的事情。 012,0.1,0.01,0.001是一些例子。因此,要以2爲基數表示這些數字,需要進行輪換。

另一個問題是,您正在處理有限的位集來表示數字並可能遇到其他舍入錯誤。此外,您距離0越遠,數字越多,無法精確表示,因此會發生舍入。

還有其他幾個問題。大多數在下面的文件中提到。 對於一個正式的論文看到這個:http://www.scribd.com/doc/5836/What-Every-Computer-Scientist-Should-Know-About-FloatingPoint-Arithmetic

不要使用浮動,你需要知道一個確切的數字。

1

正如其他人所說,float精度不足以保留完整結果。該BigDecimal(double)構造是精確的,所以它的看到代表一種方便的方法:

System.out.println(new BigDecimal(32000.0001f)); // as float 
System.out.println(new BigDecimal(32000.0001d)); // as double 

它顯示此:

32000 
32000.00010000000111176632344722747802734375 
+0

如果從文本解析它,則應該使用BigDecimal(String)構造函數;會給出更好的精度 – 2010-08-09 14:42:30

+0

@Sanjay Manohar:正確;這只是比較相應的'float'和'double'值的十進制表示形式的一種便捷方式。這個計算器是一種替代方法:http://babbage.cs.qc.edu/IEEE-754/Decimal.html – trashgod 2010-08-09 14:58:08