BigDecimal r = a.divide(b, 4, RoundingMode.HALF_UP);
System.out.println(r.setScale(2, RoundingMode.HALF_UP));

计算单价占比时直接 divide,结果抛出无法终止的十进制展开异常。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。

原因不复杂,不能整除的除法会产生无限小数,未指定精度和舍入模式时直接抛异常。

围绕「BigDecimal 除法异常」排查时,命令行跑一遍比在面板里点十次有用,面板会替你做掉不少隐式操作。动手前把原文件复制一份带时间戳,出问题立刻换回去,比现场分析快得多。

一次只改一处,改完立刻验证,几个改动叠在一起,出问题就说不清是谁导致的。先做最小复现,能稳定跑出来的问题,排查成本会低一个数量级。

别只看报错的最后一行,往上看几行,真正的起因通常在上面。

处理上按这个顺序:指定保留位数与舍入模式;统一金额精度规范;避免在循环中反复构造对象。

改完只确认一件事:计算不再抛异常,结果精度与业务规则一致,报表合计能对上。

作者 9823189