写了一个业务其中包括个税计算的,哗啦啦一大片计算完,合计就差0.04。
两个原因造就这个问题。
问题一,后台程序拿到税前工资是一个计算后的double数值(12521.7391),然后用此值来计算个税。
而导出Excel后验证个税时,税前工资已经两位小数化(12521.74),用此值来计算导致误差。
原以为这样就结束了,没想到修改完还是有误差存在,由此引发了第二个问题!
问题二,java.math.BigDecimal的BUG!
有兴趣的同学可以试一下下面的程序打印出什么?
double tmp = 1025.435;
BigDecimal t2 = new BigDecimal(tmp).setScale(2,BigDecimal.ROUND_HALF_UP);
System.out.println(t2);
double doubleValue = t2.doubleValue();
System.out.println(doubleValue);
结果是 1025.43 !
百思不得其解,试了很多次,有时末位是5会进位,但大多数时候不会进位。心想BigDecimal不能用,难道要我自己写一个四舍五入的函数?java也没有提供其它的保留小数位数并四舍五入的api啊。
后来看了一篇博文才知道:
// BigDecimal方式
double f = 1025.435;
BigDecimal b = new BigDecimal(new Double(f).toString);
double f1 = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
注意:这里一定不要直接使用new BigDecimal(double)的构造方法,
而要使用new BigDecimal(new Double(1025.435).toString())的方式,不然会出现精确问题
推荐博文:java中的四舍五入——几种四舍五入的写法