BigDecimal 類的使用

BigDecimal 類的使用

一、使用 BigDecimal 的緣由

  因爲須要計算金額,全部須要高精度計算,全部須要使用 BigDecimal 類。
BigDecimal可以精確的表示一個小數,經常使用於商業和科學計算;float,double不能精確的表示一個小數。java

二、經常使用方法

2.1 加法(add)

  分別用兩種不一樣的數據類型(long 和 string)建立 BigDecimal 對象;ide

import java.math.BigDecimal;

public class BigDecimalTest {
    /**
     * 使用BigDecimal,參數類型是double類型,計算仍是不精確
     */
    @Test
    public void testAdd1(){
        BigDecimal b1 = new BigDecimal(0.05);
        BigDecimal b2 = new BigDecimal(0.01);
        System.out.println(b1.add(b2));  
        //輸出:0.06000000000000000298372437868010820238851010799407958984375
    }

    /**
     * 使用BigDecimal,參數類型是String類型,計算結果精確
     */
    @Test
    public void testAdd2(){
        BigDecimal b1 = new BigDecimal("0.05");
        BigDecimal b2 = new BigDecimal("0.01");
        System.out.println(b1.add(b2));  
        //輸出:0.06
    }
}

  從上面的結果能夠看出使用 string 類型的才能獲得精確的計算結果。全部在計算金額時注意使用 string 類型建立對象。函數

2.2 減法(subtract)

import java.math.BigDecimal;

public class BigDecimalTest {
    /**
     * 測試減法 參數類型是double類型,計算仍是不精確
     */
    @Test
    public void testSubtract1(){
        BigDecimal b1 = new BigDecimal(0.05);
        BigDecimal b2 = new BigDecimal(0.01);
        System.out.println(b1.subtract(b2));
        //輸出:0.04000000000000000256739074444567449972964823246002197265625
    }

    /**
     * 測試減法,參數類型是String類型,計算結果精確
     */
    @Test
    public void testSubtract2(){
        BigDecimal b1 = new BigDecimal("0.05");
        BigDecimal b2 = new BigDecimal("0.01");
        System.out.println(b1.subtract(b2));
        //輸出:0.04
    }
}

2.3 乘法(multiply)

import java.math.BigDecimal;

public class BigDecimalTest {
    /**
     * 測試乘法 參數類型是double類型,計算仍是不精確
     */
    @Test
    public void testMultiply1(){
        BigDecimal b1 = new BigDecimal(0.05);
        BigDecimal b2 = new BigDecimal(0.01);
        System.out.println(b1.multiply(b2));
        //輸出:0.0005000000000000000381639164714897566548413219067927041589808827754781955614304944646164585719816386699676513671875
    }

    /**
     * 測試乘法,參數類型是String類型,計算結果精確
     */
    @Test
    public void testMultiply2(){
        BigDecimal b1 = new BigDecimal("0.05");
        BigDecimal b2 = new BigDecimal("0.01");
        System.out.println(b1.multiply(b2));
        //輸出:0.0005
    }
}

2.4 除法(divide)

2.4.1 除不盡,報錯

  因爲10/3除不盡,商是無限小數,因此報錯;

  Non-terminating decimal expansion; no exact representable decimal result.測試

import java.math.BigDecimal;

public class BigDecimalTest {
   /**
     * 測試除法 參數類型是double類型
     */
    @Test
    public void testDivide1(){
        BigDecimal b1 = new BigDecimal(0.1);
        BigDecimal b2 = new BigDecimal(0.03);
        System.out.println(b1.divide(b2));
        //報錯 java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
    }

    /**
     * 測試除法,參數類型是String類型
     */
    @Test
    public void testDivide2(){
        BigDecimal b1 = new BigDecimal("0.1");
        BigDecimal b2 = new BigDecimal("0.03");
        System.out.println(b1.divide(b2));
        //報錯 java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
    }
}
2.4.2 解決辦法

  其實devide的函數定義以下:

BigDecimal.divide(BigDecimal divisor, int scale, RoundingMode roundingMode);code

  • scale爲小數位數;
  • roundingMode爲小數模式;

小數模型有如下類型:對象

  • ROUND_CEILING
    若是 BigDecimal 是正的,則作 ROUND_UP 操做;若是爲負,則作 ROUND_DOWN 操做。
  • ROUND_DOWN
    從不在捨棄(即截斷)的小數以前增長數字。
  • ROUND_FLOOR
    若是 BigDecimal 爲正,則做 ROUND_UP ;若是爲負,則做 ROUND_DOWN 。
  • ROUND_HALF_DOWN
    若捨棄部分> .5,則做 ROUND_UP;不然,做 ROUND_DOWN 。
  • ROUND_HALF_EVEN
    若是捨棄部分左邊的數字爲奇數,則做 ROUND_HALF_UP ;若是它爲偶數,則做 ROUND_HALF_DOWN 。
  • ROUND_HALF_UP
    若捨棄部分>=.5,則做 ROUND_UP ;不然,做 ROUND_DOWN 。
  • ROUND_UNNECESSARY
    該「僞舍入模式」實際是指明所要求的操做必須是精確的,,所以不須要舍入操做。
  • ROUND_UP
    老是在非 0 捨棄小數(即截斷)以前增長數字。

  全部除法應該寫成如下形式;

BigDecimal num3 = num1.divide(num2,10,ROUND_HALF_DOWN);ip

import java.math.BigDecimal;

public class BigDecimalTest {
    /**
     * 測試除法 參數類型是double類型
     */
    @Test
    public void testDivide3(){
        BigDecimal b1 = new BigDecimal(0.1);
        BigDecimal b2 = new BigDecimal(0.03);
        System.out.println(b1.divide(b2, 10, ROUND_HALF_DOWN));
        //輸出:3.3333333333
    }

    /**
     * 測試除法,參數類型是String類型
     */
    @Test
    public void testDivide4(){
        BigDecimal b1 = new BigDecimal("0.1");
        BigDecimal b2 = new BigDecimal("0.03");
        System.out.println(b1.divide(b2, 10, ROUND_HALF_DOWN));
        //輸出:3.3333333333
    }

三、小結

  1. 使用 string 類型建立 BigDecimal 對象來進行精確計算;
  2. 進行除法計算時,須要添加參數(scale)小數位數和(roundingMode)小數模式;避免出現除不盡報錯的現象;
相關文章
相關標籤/搜索