首页 > 代码库 > java精确计算之BigDecimal
java精确计算之BigDecimal
Java中的计算主要有double,float,int,long,BigDecimal
1、float和double主要用户科学计算和工程计算,它们执行二进制浮点运算,这是为了在广泛的数值范围上提供较为精确的快速近似计算而设计的。然而它们并没有提供完全精确的结果,所以不应该被用于需要精确计算的场合。
eg:
double double_price1 = 1.03;
double double_price2 = 0.42;
System.out.println("double的计算值:"+(double_price1-double_price2));
理论值:0.61
执行结果:double的计算值:0.6100000000000001
对比理论值和执行结果发现:使用double计算时结果会有误差。
2、精确计算主要使用:BigDecimal、int或long。
2.1 使用BigDecimal的缺点:
a.与基本类型相比,BigDecimal的计算很不方便,需使用BigDecimal类的一些方法,不能直接使用+ - * /等数学运算符;
b.执行效率很慢;
2.2 使用int、long的缺点:需要自己处理十进制的小数点。
3、BigDecimal使用中需要注意的问题:
3.1 new BigDecimal(String val) 优于new BigDecimal(double val)
eg:
BigDecimal bigDecimal_price1 = new BigDecimal(1.03);
System.out.println("bigDecimal_price1="+bigDecimal_price1);
执行结果:bigDecimal_price1=1.0300000000000000266453525910037569701671600341796875
分析:因为此处使用的构造方法:new BigDecimal(double val) double受精度影响,所以构造出来的BigDecimal对象与理论值有偏差。
BigDecimal bigDecimal_price3 = new BigDecimal("1.03");
System.out.println("bigDecimal_price3="+bigDecimal_price3);
执行结果:bigDecimal_price3=1.03 与理论预期无偏差。
3.2 使用divede()方法时,需注意精度。
eg1:divide(BigDecimal divisor)
System.out.println(new BigDecimal("10").divide(new BigDecimal("3")));
执行结果:抛出异常
java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
分析:
10/3的结果为无限小数,超出BigDecimal上限。
eg2:divide(BigDecimal divisor, int roundingMode)
System.out.println("0.08/12="+new BigDecimal("0.08").divide(new BigDecimal("12"),8));
执行结果:抛出异常
java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
System.out.println("0.08/12="+new BigDecimal("0.08").divide(new BigDecimal("12"),6));
执行结果:0.08/12=0.01 与预期结果有误差
为什么保留8位小数会出异常,而保留6位小数就不出异常,本人因为经验有限,未能找出答案,希望各位老鸟不吝赐教。
eg3:divide(BigDecimal divisor, int scale, RoundingMode roundingMode)
System.out.println("0.08/12="+new BigDecimal("0.08").divide(new BigDecimal("12"),8,BigDecimal.ROUND_HALF_UP));
执行结果:0.08/12=0.00666667 与预期结果一致
java精确计算之BigDecimal