2011-11-12 29 views
2

可能重複:
Java floats and doubles, how to avoid that 0.0 + 0.1 + … + 0.1 == 0.9000001?如何解決雙精度問題在Java

我怎樣才能克服在Java的Android雙乘法精度問題??請注意,我轉換一個字符串值轉換爲double值。

例如:當我乘兩個雙重價值:

double d1 = Double.valueOf("0.3").doubleValue() * Double.valueOf("3").doubleValue(); 
System.out.println("Result of multiplication : "+d1); 

我得到以下結果:0.8999999999999999

一些我得到的結果。

0.6 * 3 = 1.7999999999999998;
0.2 * 0.2 = 0.04000000000000001;

而不是上述結果我想要得到以下結果。

0.3 * 3 = 0.9;
0.6 * 3 = 1.8;
0.2 * 0.2 = 0.04;

請記住,我不是試圖把它四捨五入到最接近的整數。

+0

你試過DecimalFormat的?例如:(新的DecimalFormat(「0.00」).format(doubleValue * 1.00000)); –

回答

10

你真的應該使用java.math.BigDecimal以避免任何精度的問題,並始終使用一個BigDecimal(String)構造。

BigDecimal result = new BigDecimal("0.3").multiply(new BigDecimal("3.0")); 
+1

我認爲使用BigDecimal可以避免任何*精度問題並不準確。在一天結束時,我們必須作出一些犧牲,以在有限的內存中表示儘可能大的數字範圍。 –

+1

@AdrianMouat,我敢肯定,如果你使用的BigDecimal我指定的方式(使用'的BigDecimal(字符串)'構造函數構造它),你會避免任何精度問題,而犧牲。 – Strelok

+1

在給出的例子中,當然。但是仍然有限制。 –

0

不幸的是,我不知道一個簡單的方法來完成你所要求的。

像Strelok說,你不應該使用浮點類型,如果你需要精確的結果。但是,對於大多數目的而言,僅爲輸出指定舍入精度就足夠了。下面的代碼是接近,但並不完全,你想要什麼:

System.out.printf("Result of multiplication : %.1g\n", d1); 

有關的printf的語法的詳細信息,請參閱the java.util.Formatter documentation

1

的問題是不是乘法。它以Double.valueOf(「0.3」)開頭。該值不能完全用浮點數表示。您應該使用java.math.BigDecimal,並且您還應該在Google上提供一個標題爲「每個計算機科學家應該瞭解的浮點數」的頁面。

+2

@downvoter你在開玩笑。請解釋0.3如何在浮點數中精確表示。 – EJP