先来几组比较
System.out.println("0.3 / 0.4 = " + 0.3 / 0.4);
BigDecimal b1 = new BigDecimal(0.3);
BigDecimal b2 = new BigDecimal(0.4);
System.out.println("b1 / b2 = " + b1.divide(b2, BigDecimal.ROUND_UP));
// divide为BigDecimal的除运算方法,BigDecimal.ROUND_UP 为舍入模式,
BigDecimal b3 = new BigDecimal("0.3");
BigDecimal b4 = new BigDecimal("0.4");
System.out.println("b3 / b4 = " + b1.divide(b2));
我们预期的结果是0.75,运行结果如下:
0.3 / 0.4 = 0.7499999999999999
b1 / b2 = 0.749999999999999930611060960927720075382909518795222760
b3 / b4 = 0.75
可以看到能精确算出0.75的只有最后一种
原因分析:
由于计算机存储器的机制问题,小数的二进制表示不可能达到100%精确,只能无限接近。
BigDecimal的使用
1.BigDecimal的构造方法:
有参构造方法的参数可以是数值也可以是字符串。
推荐使用传入字符串的构造方法
2.注意:BigDecimal的四则运算结果不能表示无限的值,否则会抛出java.lang.ArithmeticException异常。比如上述例子中第二个,计算机表示结果只能无限接近,所以要加舍入模式告诉计算机显示方式。
这时可能会想传入字符串没有传入舍入模式可以正确打印。那么再举个例子:
BigDecimal b3 = new BigDecimal("10.0");
BigDecimal b4 = new BigDecimal("3.0");
System.out.println("b3 / b4 = " + b3.divide(b4));
这里打印就会抛出java.lang.ArithmeticException异常,加上舍入模式后
正常打印。
System.out.println("b3 / b4 = " + b3.divide(b4, BigDecimal.ROUND_UP));
b3 / b4 = 3.4
因为10.0 / 3.0 的结果是无限循环的,此时必须告诉BigDecimal对象,你需要什么样的结果。
BigDecimal的四则运算
BigDecimal b1 = new BigDecimal("0.3");
BigDecimal b2 = new BigDecimal("0.4");
System.out.println("b1 / b2 = " + b1.add(b2)); // 加法
BigDecimal b3 = new BigDecimal("10.0");
BigDecimal b4 = new BigDecimal("3.0");
System.out.println("b3 / b4 = " + b3.subtract(b4)); // 减法
BigDecimal b5 = new BigDecimal("10.0");
BigDecimal b6 = new BigDecimal("3.0");
System.out.println("b5 / b6 = " + b3.multiply(b4)); // 乘法
BigDecimal b7 = new BigDecimal("10.0");
BigDecimal b8 = new BigDecimal("3.0");
System.out.println("b7 / b8 = " + b3.divide(b4, BigDecimal.ROUND_HALF_UP)); // 除法
b1 / b2 = 0.7
b3 / b4 = 7.0
b5 / b6 = 30.00
b7 / b8 = 3.3
BigDecimal的舍入模式
常用的有三种:
1.BigDecimal.ROUND_UP 进一法。
2.BigDecimal.ROUND_FLOOR 去尾法。
2.BigDecimal.ROUND_HALF_UP 四舍五入法。