慧园书屋(收༵录༵原༵创༵)烟雨亭透视经典

Double转int精确度缺失问题

2019-12-01  本文已影响0人  小石读史

工作的时候突然看到钉钉群报错,提示"支付宝回调订单价格有误差",想想最近也没动这段的代码,怎么就突然出问题了呢,看代码的时候发现前人写了这样一段代码进行数据的比较

int totalAmount = (int) (Double.valueOf(req.getParameter("total_amount")) * 100);
if (orderInfo.getReceiptAmount() == totalAmount) {
}else{
logger.error("支付宝回调订单价格有误差,[queryStr] = {}", querystr);
}

这样的比较会造成什么问题呢,我们写一段测试代码你就知道答案了

package com.sc.core.wechat.service.util;

import java.math.BigDecimal;

public class Test {
    public static void main(String[] ss){
        Double d = Double.valueOf("9.90");
        System.out.println("结果1:"+d);
        Double e = Double.valueOf("9.90") * 100;
        System.out.println("结果2:"+e);
        int f = (int) (Double.valueOf("9.90") * 100);
        System.out.println("结果3:"+f);


        Double a = Double.valueOf("19.90");
        System.out.println("结果4:"+a);
        Double b = Double.valueOf("19.90") * 100;
        System.out.println("结果5:"+b);
        int c = (int) (Double.valueOf("19.90") * 100);
        System.out.println("结果6:"+c);

        int totalAmount =new BigDecimal("19.90").multiply(new BigDecimal(100)).intValue();

        System.out.println("totalAmount:"+totalAmount);
    }
}

测试结果:
结果1:9.9
结果2:990.0
结果3:990
结果4:19.9
结果5:1989.9999999999998
结果6:1989
totalAmount:1990

为什么以前没有报错,现在报错,因为以前的价格是9.9元,现在的价格是19.9元。因为系统中的单位是分,把支付宝返回的元转换为分的时候,这样写19.90就变成了1989.9999999999998,强转之后变成了1989分,丢了1分。

因为Double转int存在精度缺失问题,所以比较这类数据应该使用BigDecimal类型进行比较。改造后的代码如下:

 int totalAmount =new BigDecimal(req.getParameter("total_amount")).multiply(new BigDecimal(100)).intValue();
if (orderInfo.getReceiptAmount() == totalAmount) {
}else{
logger.error("支付宝回调订单价格有误差,[queryStr] = {}", querystr);
}
上一篇下一篇

猜你喜欢

热点阅读