使用BigDecimal進行精確運算

首先咱們先來看以下代碼示例:java

public class Test_1 {
    public static void main(String[] args) {
        System.out.println(0.06+0.01);
        System.out.println(1.0-0.42);
        System.out.println(4.015*100);
        System.out.println(303.1/1000);
    }
    
}

 運行結果以下。ide

         0.06999999999999999工具

         0.5800000000000001spa

         401.49999999999994code

         0.30310000000000004對象

你認爲你看錯了,但結果倒是是這樣的。問題在哪裏呢?緣由在於咱們的計算機是二進制的。浮點數沒有辦法是用二進制進行精確表示。咱們的CPU表示浮點數由兩個部分組:指數和尾數,這樣的表示方法通常都會失去必定的精確度,有些浮點數運算也會產生必定的偏差。如:2.4的二進制表示並不是就是精確的2.4。反而最爲接近的二進制表示是 2.3999999999999999。浮點數的值其實是由一個特定的數學公式計算獲得的。ip

          其實javafloat只能用來進行科學計算或工程計算,在大多數的商業計算中,通常採用java.math.BigDecimal類來進行精確計算。ci

          在使用BigDecimal類來進行計算的時候,主要分爲如下步驟:數學

              一、用float或者double變量構建BigDecimal對象。it

             二、經過調用BigDecimal的加,減,乘,除等相應的方法進行算術運算。

             三、把BigDecimal對象轉換成floatdoubleint等類型。

          通常來講,可使用BigDecimal的構造方法或者靜態方法的valueOf()方法把基本類型的變量構建成BigDecimal對象。

1 BigDecimal b1 = new BigDecimal(Double.toString(0.48));
2 BigDecimal b2 = BigDecimal.valueOf(0.48);

對於經常使用的加,減,乘,除,BigDecimal類提供了相應的成員方法。

1 public BigDecimal add(BigDecimal value);                        //加法2 public BigDecimal subtract(BigDecimal value);                   //減法 3 public BigDecimal multiply(BigDecimal value);                   //乘法4 public BigDecimal divide(BigDecimal value);                     //除法

 進行相應的計算後,咱們可能須要將BigDecimal對象轉換成相應的基本數據類型的變量,可使用floatValue()doubleValue()等方法。

          下面是一個工具類,該工具類提供加,減,乘,除運算。

public class Arith {
    /**
     * 提供精確加法計算的add方法
     * @param value1 被加數
     * @param value2 加數
     * @return 兩個參數的和
     */
    public static double add(double value1,double value2){
        BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
        BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
        return b1.add(b2).doubleValue();
    }
    
    /**
     * 提供精確減法運算的sub方法
     * @param value1 被減數
     * @param value2 減數
     * @return 兩個參數的差
     */
    public static double sub(double value1,double value2){
        BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
        BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
        return b1.subtract(b2).doubleValue();
    }
    
    /**
     * 提供精確乘法運算的mul方法
     * @param value1 被乘數
     * @param value2 乘數
     * @return 兩個參數的積
     */
    public static double mul(double value1,double value2){
        BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
        BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
        return b1.multiply(b2).doubleValue();
    }
    
    /**
     * 提供精確的除法運算方法div
     * @param value1 被除數
     * @param value2 除數
     * @param scale 精確範圍
     * @return 兩個參數的商
     * @throws IllegalAccessException
     */
    public static double div(double value1,double value2,int scale) throws IllegalAccessException{
        //若是精確範圍小於0,拋出異常信息
        if(scale<0){         
            throw new IllegalAccessException("精確度不能小於0");
        }
        BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
        BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
        return b1.divide(b2, scale).doubleValue();    
    }
}
相關文章
相關標籤/搜索