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、小结
- 使用 string 类型创建 bigdecimal 对象来进行精确计算;
- 进行除法计算时,需要添加参数(scale)小数位数和(roundingmode)小数模式;避免出现除不尽报错的现象;