BigDecimal使用及Double运算精度丢失问题处理
BigDecimal使用(优点:可保持计算精度)
运算公式:
public BigDecimal add(BigDecimal value);//加法
public BigDecimal subtract(BigDecimal value);//减法
public BigDecimal multiply(BigDecimal value);//乘法
public BigDecimal divide(BigDecimal value);//除法
public BigDecimal min(BigDecimal val);//比较大小返回小
public BigDecimal max(BigDecimal val);//比较大小返回大
比较大小
a.compareTo(b)//返回值 (小于-1、等于0、大于1)
BigDecimal重写了equals方法方便我们进行大小的比较,equals不仅比较大小,还进行精度的比较。
使用string类型额构造函数进行构造时,添加了多余的0,发现c与d并不相等。而compareTo方法则只会进行大小的比较,与精度无关。
使用valueof方法进行构造时,他会帮我们去掉多余的精度,这样使用equals方法进行比较时也不会发生错误。但是在比较大小的时候还是推荐使用compareTo方法进行比较。
使用BigDecimal的double类型的构造参数生成对象再进行相加,结果也并不精确
double amt = 1.02;
double avgamt = 1.01;
System.out.println(amt+avgamt); //2.0300000000000002
BigDecimal bdAmt = new BigDecimal(amt);
BigDecimal bdAvgAmt = new BigDecimal(avgamt);
BigDecimal add = bdAmt.add(bdAvgAmt);
System.out.println(add);//2.03000000000266453525910037569701671600341796875
所以这里我们需要注意的是直接使用new 的方式构建对象的时候需要使用string类型的构造函数才能保证精确。更好一点的做法是使用静态方法valueOf进行初始化。解决方式:
1.使用string类型的构造函数
BigDecimal bdAmt = new BigDecimal(Double.toString(amt));
BigDecimal bdAvgAmt = new BigDecimal(Double.toString(avgamt));
BigDecimal add = bdAmt.add(bdAvgAmt);
System.out.println(add); //2.03
使用静态方法valueOf进行初始化(推荐)
BigDecimal bdAmt = BigDecimal.valueOf(amt);
BigDecimal bdAvgAmt = BigDecimal.valueOf(avgamt);
BigDecimal add = bdAmt.add(bdAvgAmt);
System.out.println(add); //2.03