Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。
在实际应用中,特别是商业计算往往要求结果更加精确。运用BigDecimal可以很方便的解决这个问题。
1. 构造方法:
BigDecimal b1 = new BigDecimal("0.06");
BigDecimal b2 = new BigDecimal("0.01");
参数可以为double,String ,int ,long等
2. 转变为double,float,int 等对象
b.doubleValue();
b.floatValue();
b.intValue();
b1.longValue();
3.加减乘除
加
BigDecimal e = new BigDecimal(2.2);
BigDecimal f = new BigDecimal(3.32);
System.out.println(e.add(f));
结果是5.520000000000000017763568394002504646778106689453125
减
BigDecimal b1 = new BigDecimal(1.0);
BigDecimal b2 = new BigDecimal(0.42);
System.out.println(b1.subtract(b2));
结果:0.580000000000000015543122344752191565930843353271484375
乘
BigDecimal b1 = new BigDecimal(4.015);
BigDecimal b2 = new BigDecimal(100);
System.out.println(b1.multiply(b2));
结果:401.49999999999996802557689079549163579940795898437500
除
BigDecimal b1 = new BigDecimal(303.1);
BigDecimal b2 = new BigDecimal(1000);
System.out.println(b1.divide(b2));
结果是:0.3031000000000000227373675443232059478759765625
注意ArithmeticException异常,除数不能为0
4.保留小数位数 setScale()方法
BigDecimal.ROUND_HALF_UP //四舍五入的处理 1.155保留两位小数就是1.16
BigDecimal.ROUND_HALF_DOWN//四舍五入的处理 1.155保留两位小数,则是1.15,是5和小于5的不会进位,超过5的才会进位
BigDecimal.ROUND_DOWN//直接删除多余的位数,1.155保留两位小数就是1.15
BigDecimal.ROUND_UP//进位处理,1.12445保留两位小数就是1.13,从最后一位一直向前进位
BigDecimal e = new BigDecimal(2.2);
BigDecimal f = new BigDecimal(3.32);
System.out.println(e.add(f));
BigDecimal bigDecimal = e.add(f).setScale(2, BigDecimal.ROUND_HALF_UP);//保留两位小数的四舍五入
System.out.println(bigDecimal);
即使使用上面的方法也有可能造成精度的丢失
double t = 0.155;
BigDecimal b = new BigDecimal(t);
double f1 = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
结果为0.15 而不是0.16
这是因为浮点数的精度丢失,bigdecimal处理的也是丢失精度的数据,所以会出现上面的问题,可以将double t转换为字符串再作为BigDecimal的参数使用
精度丢失原因
计算机使用的是二进制表示,而我们的数是十进制的,十进制数的二进制表示形式可能不精确。
double t = 0.155;
BigDecimal b = new BigDecimal(t+“”);
double f1 = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
结果是0.16