一分钱的Bug(求助帖)

背景,某个用户反馈线上后台提现金额到账少了一分钱,其输入的提现金额是19320.38(元),但实际银行到账金额1932037(分),也就是少了一分钱。然后立马翻看代码,以及运行日志。

伪代码如下:

less 复制代码
@PostMapping("withDrawApply")
Result withdrawApply(@RequestBody Map<String,Object> param){
   Object amount = params.get("amount");
   toWithdrawApply(new BigDecimal(String.valueOf(amount));
}

Boolean  toWithdrawApply(BigDecimal amount){
      
    Map<String,Objct> param = new HashMap();
    param.put("amount", amount.multiply(new BigDecimal(100)).intValue());
    //TODO HTTP调用
    //此处大意就是将提现参数提交给支付机构;其他参数省略
    异步保存提现记录,此处提现记录中Record中的金额字段amount也取自:amount,保存的数据为19320.38
    return flag;
}

通过日志排查,在提交给第三方支付机构的参数日志中,amount金额变成了1932079。 所以总结下过程就是:用户提交金额19320.80,然后double经过String.value,转BigDeciaml,最后乘以100,少了一分钱。

第一时间怀疑是精度缺失问题,springboot中param接收到的amount实际类型为double类型,而浮点数在二进制计算中并不能真实表示该确切的值,因此其底层可能是19320.7999999999....来表示

但是我后续经过进行模拟处理操作,进行同jdk版本,cpu架构环境的参数进行调用处理,一直不能重现。所以很好奇这到底是和什么原因有关?如果是精度缺失按道理每次都会重现吧? 如果是精度缺失问题,正常的处理方式应该是什么呢? 期待各位大佬答疑。

相关推荐
Java面试题总结8 小时前
java高频面试题(2026最新)
java·开发语言·jvm·数据库·spring·缓存
苦逼的猿宝8 小时前
学生心理咨询评估系统
java·毕业设计·springboot·计算机毕业设计
隔窗听雨眠8 小时前
doctype、charset、meta如何控制整个渲染流水线
java·服务器·前端
西安邮电大学10 小时前
SpringBean完整生命周期
java·spring
刀法如飞10 小时前
DDD 与 Ontology 对比分析:哪一种更适合AI时代复杂系统构建?
java·架构·领域驱动设计
SunnyDays101110 小时前
Java 读写 Excel 公式:从基础到高级的实战总结
java·开发语言·excel
wb0430720110 小时前
Java 26
java·开发语言
白露与泡影10 小时前
JVM GC调优实战:从线上频繁Full GC到RT降低80%的全过程
java·开发语言·jvm
范什么特西10 小时前
Spring 动态代理 静态代理
java·后端·spring
醇氧10 小时前
Spring 动态注册 Bean 深度解析:从源码到实践
java·后端·spring