Double转int精确度缺失问题

作者: 小石读史 | 来源:发表于2019-12-01 10:05 被阅读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);
    }
    

    相关文章

      网友评论

        本文标题:Double转int精确度缺失问题

        本文链接:https://www.haomeiwen.com/subject/lctawctx.html