1. 程式人生 > >double型別相加(減、乘、除)結果會有些誤差

double型別相加(減、乘、除)結果會有些誤差

前提介紹

      今天在除錯程式碼的時候發現了一個double型別資料相減的有趣問題,148163.1 - 82692.09大家猜猜結果等於多少,經過除錯最終為5471.010000000009。

是不是很奇怪,下面將說明這其中的奧妙!

原因說明

     double屬於floating binary point types,也就是說都double型的數值在相加減的時候,會將數值轉換成二進位制的數值如10001.10010110011這種表示發再做相加減,但是在轉換成二進位制程式碼表示的時候,儲存小數部分的位數會有不夠的現象,即無限迴圈小數,這就是造成微差距的主要原因。

解決方法

1.只取需要用到的位數:

 小數點臺後面的位數部分就不要管了,不過這種方法不太好。

 2.使用Decimal型別:

用Decimal就不會出現上面的問題了,可以準確的計算小數值,知識Decimal的範圍比double小,一般情況下也夠用了

 Decimal型別的有效位數達到28位,而double型別的16位,所以Decimal型別比Double型別能表示更精確的浮點數。

總結

1.在double型別數值進行比較大小的情況最好使用1.02-1.01==double.MinValue這種方式進行判斷

2.使用double型別進行加減的情況下看看能否使用Decimal型別進行計算

package org.lxh.demo11.numberdemo;
    import java.math.BigDecimal;
    class MyMath {
        public static double add(double d1, double d2)
    {        // 進行加法運算
             BigDecimal b1 = new BigDecimal(d1);
             BigDecimal b2 = new BigDecimal(d2);
            return b1.add(b2).doubleValue();
         }
        public static double sub(double d1, double d2)
    {        // 進行減法運算
             BigDecimal b1 = new BigDecimal(d1);
             BigDecimal b2 = new BigDecimal(d2);
            return b1.subtract(b2).doubleValue();
         }
        public static double mul(double d1, double d2)
    {        // 進行乘法運算
             BigDecimal b1 = new BigDecimal(d1);
             BigDecimal b2 = new BigDecimal(d2);
            return b1.multiply(b2).doubleValue();
         }
        public static double div(double d1,
    double d2,int len) {// 進行除法運算
             BigDecimal b1 = new BigDecimal(d1);
             BigDecimal b2 = new BigDecimal(d2);
            return b1.divide(b2,len,BigDecimal.
    ROUND_HALF_UP).doubleValue();
         }
        public static double round(double d,
    int len) {     // 進行四捨五入
    操作
             BigDecimal b1 = new BigDecimal(d);
             BigDecimal b2 = new BigDecimal(1);
            // 任何一個數字除以1都是原數字
            // ROUND_HALF_UP是BigDecimal的一個常量,
    表示進行四捨五入的操作
            return b1.divide(b2, len,BigDecimal.
    ROUND_HALF_UP).doubleValue();
         }
    }
    public class BigDecimalDemo01 {
        public static void main(String[] args) {
             System.out.println("加法運算:" +
    MyMath.round(MyMath.add(10.345,
    3.333), 1));
             System.out.println("乘法運算:" +
    MyMath.round(MyMath.mul(10.345,
    3.333), 3));
             System.out.println("除法運算:" +
    MyMath.div(10.345, 3.333, 3));
             System.out.println("減法運算:" +
    MyMath.round(MyMath.sub(10.345,
    3.333), 3));
         }
    }