1.前言
在设计数据库时或者是java中的Bean对象经常会使用到BigDecimal类型来定义,尤其是在和价格相关的字段,其实是因为float和double在计算时会产生精度丢失的问题,于是在进行非常精确的浮点数计算时就必须要使用bigDecimal。
2.为什么float和double会产生精度丢失问题?
在计算机底层进行数据计算都是将数据转换为2进制数字进行计算,但是在有些浮点数转换的时候会出现循环小数或者长度超过计算机保存范围被截取这种情况,于是就会产生精度丢失问题。比如
double d1=0.1;
double d2=0.2;
double d3=d1+d2;
System.out.println(d3); //d3=0.30000000000000004
3.为什么bigdecimal不会丢失精度
bigDecimal在进行数据计算的时候将浮点类型转换成整数进行计算,避免了这一问题。但是也不是完全不会产生精度问题,在bigDecimal中使用String的构造器才会彻底解决精度问题,在其他类型中也会产生,比如使用double构造器只是会使得计算结果精确位数更高。
BigDecimal bigDecimal = new BigDecimal(0.1);
BigDecimal bigDecimal2 = new BigDecimal(0.2);
System.out.println(bigDecimal.add(bigDecimal2));
//0.3000000000000000166533453693773481063544750213623046875
BigDecimal bigDecimal3 = new BigDecimal("0.1");
BigDecimal bigDecimal4 = new BigDecimal("0.2");
System.out.println(bigDecimal3.add(bigDecimal4));
//0.3
4.bigDecimal的常用方法
//BigDecimal的常用方法
//加减乘除
BigDecimal add = bigDecimal3.add(bigDecimal4);
BigDecimal subtract = bigDecimal3.subtract(bigDecimal4);
BigDecimal multiply = bigDecimal3.multiply(bigDecimal4);
BigDecimal divide = bigDecimal3.divide(bigDecimal4); //除一般需要设置保存数据的范围
BigDecimal divide2 = bigDecimal3.divide(bigDecimal4,2, RoundingMode.HALF_UP);//设置保留范围和精确规则
System.out.println("原数为"+bigDecimal3+"和"+bigDecimal4+"——加的结果是"+add+"减的结果是"+subtract+"乘的结果是"+multiply+"除得结果是"+divide2);
BigDecimal abs = bigDecimal3.abs();
int i = bigDecimal3.compareTo(bigDecimal4);
BigDecimal pow = bigDecimal3.pow(2);
System.out.println("绝对值,对比,求指数幂的结果分别为:"+abs+","+i+","+pow);