当Double遇见Integer撞上大大的BigDecimal擦出优美的误差

70 阅读1分钟

当Double遇见Integer撞上大大的BigDecimal擦出优美的误差


在解决误差前先问一个问题

数据库中字段为decimal类型,VO中能将字段设置为decimal类型吗?
答案是不能,VO层数据类型是Double类型。
所以是躲不过分数和整数的运算,而分数和整数运算就会有一定的误差,这对一些银行金融项目影响是巨大的,也是不可以的。

那肯定就会说上BigDecimal,但是上了BigDecimal就可以高枕无忧了吗? NO,我之前也以为是这样,但问题才刚刚开始。 废话少说上代码:

public static void main(String[] args) {
            Integer i = 100;
            Double d = 598.81;
            Double c = d * i;
            System.out.println(c);
}

输出:

59880.99999999999


那我转换为BigDecimal
public static void main(String[] args) {
            Integer i = 100;
            Double d = 598.81;
            Double c = d * i;
            BigDecimal multiply = new BigDecimal(d).multiply(new BigDecimal(i));
            System.out.println(multiply);
            System.out.println(c);
}

输出:

59880.99999999999454303178936243057250976562500 59880.99999999999

咦~~~,怎么小数点不降反增了,找到BigDecimal文档中查看,原来直接将浮点类型转换为BigDecimal类型会有误差,官方是建议将浮点类型先转为String类型,再转为BigDecimal类型再进行运算才不会出现误差。

那我再转,将Double转为String类型再试试

public static void main(String[] args) {
            Integer i = 100;
            Double d = 598.81;
            Double c = d * i;
            BigDecimal multiply1 = new BigDecimal(d).multiply(new BigDecimal(i));
            
            String a = d.toString();
            BigDecimal multiply1 = new BigDecimal(a).multiply(new BigDecimal(i));
            System.out.println(a);
            System.out.println(c);
            System.out.println(multiply);
            System.out.println(multiply1);
}

输出:

598.81 59880.99999999999 59880.99999999999454303178936243057250976562500 59881.00

这下终于解决了。

我是时生,一个正在努力的小白。欢迎批评,欢迎指正,欢迎共享。 如果这篇文章对你有帮助,麻烦点个赞呗!