2016-02-23 173 views
0

我在使用BigDecimal執行除法時得到不正確的結果。 NUMBER1 = 221500.0 數字2 = 12.0 這裏是我的代碼片段:BigDecimal.Divide給出的結果不正確

BigDecimal d1 = new BigDecimal(String.valueOf(number1)).setScale(13, 4); 
BigDecimal d2 = new BigDecimal(String.valueOf(number2)).setScale(13, 4); 
return (d1.divide(d2, 13, 4)).doubleValue(); 

18458.333333333332

,如果我使用計算器它給 18458.333333333333333333333333333

讓我知道任何問題進行同樣的計算處理BigDecimal中的比例。如果有人讓我知道如何與計算器達到相同的結果,這將會有所幫助。

+1

這是正確的結果。你真的需要這麼長的結果嗎? –

+0

*確切*相同的結果?你的計算器是否吐出適量的3s,或者?實際上有3個無限的數量。 –

+1

由於您需要13個值,BigDecimal正在如何工作。如果您的目的要求「精確的除法結果」,爲了比較目的,請乘以某個預先確定的閾值並作爲整數進行比較。在你的情況下,'double'不能保持這個值,所以舍入。 –

回答

4

你問了divide()調用13位數的精度,這就是它給你的。

然後,您將其轉換爲double,並注意double無法處理該精度。

BigDecimal d1 = new BigDecimal(String.valueOf(221500.0)).setScale(13, BigDecimal.ROUND_HALF_UP); 
BigDecimal d2 = new BigDecimal(String.valueOf(12.0)).setScale(13, BigDecimal.ROUND_HALF_UP); 
BigDecimal d3 = d1.divide(d2, 13, BigDecimal.ROUND_HALF_UP); 
System.out.println("BigDecimal: " + d3); 
System.out.println("as double : " + d3.doubleValue()); 

輸出

BigDecimal: 18458.3333333333333 
as double : 18458.333333333332 

如果你要扔掉通過BigDecimal獲得了額外的精度,爲什麼不只是做double數學?


在不同的音符:
不要做new BigDecimal(String.valueOf(doubleValue))。使用BigDecimal.valueOf(doubleValue)

設置d1d2的比例似乎沒有意義。
除非明確需要,否則儘可能晚回合。

+2

@Andreas在說什麼,不要調用.doubleValue()這樣做會將您的高精度數字轉換爲不太精確的雙精度 – Arkiliknam

3

有些事情你應該做不同的事情。

正如你已經知道,BigDecimal的是一個偉大的工具,因爲:

  • 它可以保留小數位數完全相同,不同於任何浮點表示如浮動

  • 它可以使用任意大的十進制數,不像int,double and float

然而,使其工作時,你應保持幾件事情:

  • 設置值時爲BigDecimal,總是使用字符串表示,因爲只有字符串表示將處理小數精度。例如,新的BigDecimal(String。valueOf(number1))是一個壞主意,如果number是一個double(不能處理精確的小數),那麼你將把這個不精確的數字轉換爲BigDecimal。

  • 創建BigDecimal時不要限制精度。通常BigDecimal會保持輸入的精度,即新的BigDecimal(「3.234」)將有3個十進制數字。

  • 請在每次劃分後設置roudingMode。有關可能的排隊模式,請參閱JavaDoc,HALF_EVEN是常見用例的最佳選擇。

  • 設置除法的小數精度,因爲除法可能導致無窮的小數位數。

考慮這個例子:

public class BigDecimalTest { 

    public static void main(final String[] args) { 
     final BigDecimal d1 = new BigDecimal("221500"); 
     final BigDecimal d2 = new BigDecimal("12"); 
     final BigDecimal result=d1.divide(d2,30,RoundingMode.HALF_EVEN); 
     System.out.println(result); 
    } 

} 

這給

18458.333333333333333333333333333333

與要求所有的30位小數。隨意改變30〜300這給

18458.333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333

很多比計算器更好,不是嗎? :)