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);
}