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)小数模式;避免出现除不尽报错的现象;
相关文章
相关标签/搜索