2011-04-05 73 views
4

我有以下代碼:計算兩個雙打的其餘部分的Java

Double x = 17.0; 
Double y = 0.1; 

double remainder = x.doubleValue() % y.doubleValue(); 

當我運行此我得到的餘數= 0.09999999999999906

任何想法,爲什麼?

我基本上需要檢查x是否完全被y整除。你能否建議用java做替代方法?

謝謝

+1

浮點運算僅是實數運算的近似值:http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems – LumpN 2011-04-05 13:13:36

回答

10

由於如何表示浮點數。

如果你想要的精確值,使用BigDecimal

BigDecimal remainder = BigDecimal.valueOf(x).remainder(BigDecimal.valueOf(y)); 

另一種方式來那就是多了10(或100,1000),轉換爲int每個值,然後使用%

3

您需要比較允許舍入誤差的結果。

if (remainder < ERROR || remainder > 0.1 - ERROR) 

而且,當你想使用double

+0

這是正確的當你的數據確實來自浮點/雙精度源(並且不僅僅是離散數據僞裝成浮點值)時使用的答案,並且你想知道「x」是否「非常接近」y的精確倍數'。 – 2015-06-19 21:48:31

1

This後應該幫助你不使用雙。它解釋了爲什麼你看到這種行爲,並且還討論了BigDecimal類。

+0

您至少應該引用該鏈接中與OP最重要的部分。否則,這聽起來像你沒有給予太多的關注。 – 2016-01-28 03:43:07

1

在計算機上期望雙算術的精確結果是有問題的。基本的罪魁禍首是我們人類大多使用10號基地,而計算機通常以2號基地存儲數字。兩者之間存在轉換問題。

該代碼會做你想要什麼:

public static void main(String[] args) { 
    BigDecimal x = BigDecimal.valueOf(17.0); 
    BigDecimal y = BigDecimal.valueOf(0.1); 

    BigDecimal remainder = x.remainder(y); 
    System.out.println("remainder = " + remainder); 

    final boolean divisible = remainder.equals(BigDecimal.valueOf(0.0)); 
    System.out.println("divisible = " + divisible); 

} 
+1

只是一個補充:你可以使用'BigDecimal.ZERO'而不是'valueOf(0.0)'來提高可讀性。如果可能的話,最好使用'new BigDecimal(String)'構造函數,因爲'valueOf(double)'仍然存在精度/舍入錯誤。 – 2011-04-05 13:48:31