一分钱的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架构环境的参数进行调用处理,一直不能重现。所以很好奇这到底是和什么原因有关?如果是精度缺失按道理每次都会重现吧? 如果是精度缺失问题,正常的处理方式应该是什么呢? 期待各位大佬答疑。

相关推荐
自不量力的A同学5 小时前
Solon AI v3.9 正式发布:全能 Skill 爆发
java·网络·人工智能
万岳科技系统开发6 小时前
食堂采购系统源码库存扣减算法与并发控制实现详解
java·前端·数据库·算法
独断万古他化6 小时前
【Spring 原理】Bean 的作用域与生命周期
java·后端·spring
*小海豚*6 小时前
在linux服务器上DNS正常,但是java应用调用第三方解析域名报错
java·linux·服务器
撩得Android一次心动6 小时前
Android LiveData 全面解析:使用Java构建响应式UI【源码篇】
android·java·android jetpack·livedata
组合缺一6 小时前
Solon AI (Java) v3.9 正式发布:全能 Skill 爆发,Agent 协作更专业!仍然支持 java8!
java·人工智能·ai·llm·agent·solon·mcp
MSTcheng.6 小时前
【C++】C++11新特性(二)
java·开发语言·c++·c++11
一 乐6 小时前
校园二手交易|基于springboot + vue校园二手交易系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端
KIKIiiiiiiii6 小时前
微信个人号API二次开发中的解决经验
java·人工智能·python·微信
80530单词突击赢6 小时前
SpringBoot整合SpringMVC全解析
java·spring boot·后端