因为须要计算金额,全部须要高精度计算,全部须要使用 BigDecimal 类。
BigDecimal可以精确的表示一个小数,经常使用于商业和科学计算;float,double不能精确的表示一个小数。java
分别用两种不一样的数据类型(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 类型建立对象。函数
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 } }
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 } }
因为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. } }
其实devide的函数定义以下:
BigDecimal.divide(BigDecimal divisor, int scale, RoundingMode roundingMode);code
小数模型有如下类型:对象
全部除法应该写成如下形式;
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 }