2015-10-30 21 views
4

我有一個方法,輸入兩個值double值。當試圖將它們加在一起時,我在一定的閾值上得到不正確的值,所以我開始使用BigDecimal使用Java BigDecimal仍然不正確解決

但即使有BigDecimal我仍然有不正確的值?

double value1 = 2789.45; 
double value2 = 557.89; 
System.out.println(BigDecimal.valueOf(value1 + value2)); 

打印

3347.3399999999997 

當它應該

3347.34 

看我如何正確地做到這一點,即使value1value2可能比目前的範圍高? (它們是以單獨的方法計算的)。

我應該只使用舍入?

回答

8

我應該只使用舍入嗎?

NOPE,你遇到的是失去double總和的精度。


你是第一個(value1 + value2)suming雙打和雙總和(已失去精度)轉換爲BigDecimal後。

爲了避免這種使用這個代替:

double value1 = 2789.45; 
double value2 = 557.89; 
System.out.println(BigDecimal.valueOf(value1).add(BigDecimal.valueOf(value2))); 

OUTPUT:

3347.34 

工作IDEONE DEMO here


UPDATE

-1。代替使用仍然脆弱的BigDecimal.valueOf,您應該從頭開始使用BigDecimal,並使用new BigDecimal("2789.45"),new BigDecimal("557.89")來創建它們。只要您使用了double文字,就會引入不精確。 BigDecimal.valueOf試圖讓它回來,但它並不總是工作。 - Louis Wasserman

其實我並不完全同意這一點。你不能硬編碼值創造新的小數,有什麼我可以同意被讀取值(如果可能的OP)在String直接避免double精度丟失:

String value1 = "2789.45"; 
BigDecimal one = new BigDecimal(value1); 
String value2 = "557.89"; 
BigDecimal two = new BigDecimal(value2); 
System.out.println(one.add(two)); 

OUTPUT:

3347.34 

這將避免Louis Wasserman注意到的問題。

新的工作演示

+1

呵呵你打我吧:) – Mena

+1

一個榮譽擊敗你@Mena :)謝謝 –

+1

謝謝,作品完美 –

1

因爲編譯器將首先評估的總和,它增加了兩個doubles第一,因此你失去精度,你基本上是這樣

double value1 = 2789.45; 
double value2 = 557.89; 
double sum = value1 + value2; // precision lost here 
System.out.println(BigDecimal.valueOf(sum)); 
1

你已經失去精度時您將變量分配給雙打。

考慮此程序:

import java.math.BigDecimal; 

public class Test { 
    public static void main(String[] args) { 
    System.out.println(new BigDecimal(2789.45)); 
    System.out.println(new BigDecimal("2789.45")); 
    } 
} 

輸出:

2789.4499999999998181010596454143524169921875 
2789.45 

做在BigDecimal的加入將讓你的輸入的確切數額,但如果你先轉換爲double的投入將是最接近你寫的值的雙打。