由于需要计算金额,所有需要高精度计算,所有需要使用 bigdecimal 类。
bigdecimal能够精确的表示一个小数,常用于商业和科学计算;float,double不能精确的表示一个小数。
分别用两种不同的数据类型(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 类型创建对象。
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);
小数模型有以下类型:
所有除法应该写成以下形式;
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 }
如对本文有疑问, 点击进行留言回复!!
SpringBoot引用阿里easyexcel,Excel导出返回浏览器下载
HashMap、Hashtable、ConcurrentHashMap三者间的异同
解决RecycleView 中Item包含Edittext时,滑动view复用导致数据错乱的问题
多线程、同步工作原理、死锁案例、Lock接口、线程的生命周期的讲解及实现
网友评论