欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

BigDecimal 类的使用

程序员文章站 2022-12-29 15:29:11
BigDecimal 类的使用 1、使用 BigDecimal 的原因   由于需要计算金额,所有需要高精度计算,所有需要使用 BigDecimal 类。 BigDecimal能够精确的表示一个小数,常用于商业和科学计算;float,double不能精确的表示一个小数。 2、常用 ......

bigdecimal 类的使用

1、使用 bigdecimal 的原因

  由于需要计算金额,所有需要高精度计算,所有需要使用 bigdecimal 类。
bigdecimal能够精确的表示一个小数,常用于商业和科学计算;float,double不能精确的表示一个小数。

2、常用方法

2.1 加法(add)

  分别用两种不同的数据类型(long 和 string)创建 bigdecimal 对象;

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);

  • 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);

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
    }

3、小结

  1. 使用 string 类型创建 bigdecimal 对象来进行精确计算;
  2. 进行除法计算时,需要添加参数(scale)小数位数和(roundingmode)小数模式;避免出现除不尽报错的现象;