2014-10-03 129 views
2

當我這樣做浮點值解析Java中

value = Float.parseFloat("5555998.558f"); 

System.out.println("Value: " + value); 

它給我造成5555998.5而不是5555998.558 我使用了一些計算的變量值。我需要的確切數值,即5555998.558

如何克服這一點?

+3

爲什麼你使用float而不是double? – 2014-10-03 16:32:02

+1

爲什麼使用原始的浮點數據類型而不是'BigDecimal'? – Makoto 2014-10-03 16:32:45

+0

價值來自一個文本框這就是爲什麼我這樣做。 – 2014-10-03 16:33:34

回答

7

該高值的float值精度僅爲0.5,因此Java將其解析爲最接近的值float它可能= 5555998.5,這就是打印的內容。

要查看2個最接近值之間的差值在這個幅度,(最後一位單位)使用Math.ulp

String s = "5555998.558f"; 
float value = Float.parseFloat(s); 
System.out.println(value); 
System.out.println(Math.ulp(value)); 

這將打印

5555998.5 
0.5 

您可以使用double其中有精度要好得多:

double d = Double.parseDouble(s); 
System.out.println(d); 
System.out.println(Math.ulp(d)); 

This print

5555998.558 
9.313225746154785E-10 

有趣的是,Double.parseDouble似乎並不介意到底fDouble.parseDoubleString轉換爲double「由double類的valueOf方法執行」。而Double.valueOf狀態:

的floatValue:

  • Signopt NaN的

  • Signopt無限

  • Signopt FloatingPointLiteral

  • Signopt HexFloatingPointLiteral

  • SignedInteger

這種方法將需要String就好像它是一個Java數字文字,哪個Java與端部的支持f指示浮點文字。

+1

...或更好,BigDecimal將保留輸入的確切十進制值。 – 2014-10-03 16:34:53

+0

@JonSkeet當然,'BigDecimal'將具有任意的精度。但'new BigDecimal(「5555998.558f」)'拋出'NumberFormatException'因爲'f'存在。現在我很好奇爲什麼'Float.parseFloat'和'Double.parseDouble'似乎忽略了字符串中的'f'。 – rgettman 2014-10-03 16:37:51

+0

我也很驚訝,雖然它被記錄在'Float.valueOf'中。我想最好的解決方案將取決於爲什麼f'存在,以及OP真正想要達到什麼。 – 2014-10-03 16:41:40

5

BigDecimal可能是您確切的小數表示形式的最佳選擇。

BigDecimal value = new BigDecimal("5555998.558"); 

這是不變的,所以每次你做它的操作會導致你創建一個新的BigDecimal實例,但其精度也有可能你所需要的。

0

也可以這樣做:

Double value = Double.valueOf("5555998.558f"); 
System.out.println("Value: " + value); 

輸出:

Value: 5555998.558 
0

http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html 浮動:浮子數據類型是單精度32位IEEE 754浮點。其值範圍超出了本討論的範圍,但在Java語言規範的浮點類型,格式和值部分中進行了指定。與對byte和short的建議一樣,如果需要將內存保存在浮點數的大數組中,請使用float(而不是double)。此數據類型不應用於精確值,例如貨幣。爲此,您需要改爲使用java.math.BigDecimal類。 Numbers和Strings涵蓋了Java平臺提供的BigDecimal和其他有用的類。

所以使用BigDecimal,你就沒有問題了。