簡體   English   中英

在Java中使用parseFloat的正確方法是什么

[英]What's the right way to parseFloat in Java

我注意到Java浮點精度的一些問題

       Float.parseFloat("0.0065") - 0.001  // 0.0055000000134110451
       new Float("0.027") - 0.001          // 0.02600000000700354575
       Float.valueOf("0.074") - 0.001      // 0.07399999999999999999

我不僅有Float的問題,還有Double

有人可以解釋幕后發生的事情,我們怎樣才能獲得准確的數字? 在處理這些問題時,處理此問題的正確方法是什么?

問題在於float具有有限的精度; 它不能完全代表0.0065 (當然, double也是如此:它具有更高的精度,但仍然是有限的。)

使上述問題更加明顯的另一個問題是0.001是一個double而不是float ,所以你的float被提升為double來執行減法,當然在這一點上系統無法恢復double 可能代表的缺失精度。 為了解決這個問題,你會寫:

float f = Float.parseFloat("0.0065") - 0.001f;

使用0.001f而不是0.001

看看每個計算機科學家應該知道的關於浮點運算的內容 你的結果對我來說是正確的。

如果您不喜歡浮點數的工作方式,請嘗試使用類似BigDecimal的方法

你得到了正確的結果。 沒有像0.027那樣的float ,也沒有這樣的double 如果使用floatdouble總會出現這些錯誤。

floatdouble存儲為二進制分數 :類似於1/2 + 1/4 + 1/16 ......您無法將所有十進制值精確地存儲為有限精度二進制分數。 這在數學上是不可能的。

唯一的選擇是使用BigDecimal ,您可以使用它來獲取精確的十進制值。

從“ 原始數據類型Java教程”頁面

如果浮點字面值以字母Ff結尾,則浮點字面值為float類型; 否則它的類型是雙倍的,它可以選擇以字母Dd結尾。

所以我認為你的文字( 0.001 )是雙打的,你從浮動中減去雙打。

試試這個:

System.out.println((0.0065F - 0.001D)); // 0.005500000134110451
System.out.println((0.0065F - 0.001F)); // 0.0055

......你會得到:

0.005500000134110451
0.0055

因此,在文字中添加F后綴,您應該得到更好的結果:

Float.parseFloat("0.0065") - 0.001F
new Float("0.027") - 0.001F
Float.valueOf("0.074") - 0.001F

我會將你的浮點數轉換為字符串,然后使用BigDecimal。

這個鏈接解釋得很好

new BigDecimal(String.valueOf(yourDoubleValue));

不要使用BigDecimal雙構造函數,因為你仍然會得到錯誤

如果您需要任意精度,請使用BigDecimal,不要浮動或加倍。 你會看到使用float這種性質的各種舍入問題。

另外要小心不要使用BigDecimal的float / double構造函數,因為它會有同樣的問題。 請改用String構造函數。

浮點不能准確表示十進制數。 如果您需要在Java中准確表示數字,則應使用java.math.BigDecimal類:

BigDecimal d = new BigDecimal("0.0065");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM