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

相关推荐
自由生长202413 分钟前
从流式系统中思考-C++生态和Java生态的区别
java·c++
培培说证25 分钟前
2026大专Java开发工程师,考什么证加分?
java·开发语言·python
qq_3363139326 分钟前
java基础-方法引用
java·开发语言·算法
总是学不会.29 分钟前
【JUC编程】一、线程的基础概念
java·开发语言·jvm
由之39 分钟前
Spring事件监听机制简单使用
java·spring
小鸡吃米…41 分钟前
Python - 类属性
java·前端·python
沉下去,苦磨练!43 分钟前
计算一个字符串在另一个字符串中出现次数
java·开发语言
Li_7695321 小时前
Redis —— (五)
java·redis·后端·spring
派大鑫wink1 小时前
【Day7】构造方法与 this 关键字:初始化对象的正确姿势
java·开发语言
JIngJaneIL1 小时前
基于java+ vue办公管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端