时间:2025-04-24 14:00
人气:
作者:admin
关于orderAmt.divide(divisor).setScale(2, roundingMode)与 orderAmt.divide(divisor, 2, roundingMode) ,这两个表达式的核心区别在于 是否在除法操作时明确指定精度和舍入模式,以及可能引发的行为差异。
orderAmt.divide(divisor).setScale(2, roundingMode)divide(BigDecimal divisor) 进行除法运算,未指定精度(scale)和舍入模式,此时会使用 默认舍入模式(BigDecimal.ROUND_UNNECESSARY)。divide() 会直接抛出 ArithmeticException(因为默认模式要求结果必须精确)。java.lang.ArithmeticException:
Non-terminating decimal expansion; no exact representable decimal result.
at java.math.BigDecimal.divide(BigDecimal.java:1707)
setScale(2, roundingMode) 对结果进行精度调整,使用指定的 roundingMode 舍入到 2 位小数。1 ÷ 3),第一步 divide() 会直接报错,无法进入 setScale 步骤。orderAmt.divide(divisor, 2, roundingMode)执行过程:
直接调用 divide(BigDecimal divisor, int scale, RoundingMode roundingMode) 三参数重载方法,在除法运算的同时指定精度(2位小数)和舍入模式。
scale 和 roundingMode 进行舍入,不会抛出异常(除非除数为 0)。优势:
一步完成除法和舍入,避免因默认舍入模式导致的异常,且逻辑更清晰(明确告知“除法后保留2位小数,按指定方式舍入”)。
| 对比项 | 表达式1(先除后设精度) | 表达式2(除法时指定精度和舍入) |
|---|---|---|
| 舍入时机 | 先除法(默认模式),再单独舍入 | 除法过程中直接按指定精度和模式舍入 |
| 异常风险 | 若除法结果不精确,第一步就会报错 | 不会报错(除数非0时),强制按规则舍入 |
| 代码意图 | 不明确(未显式声明精度要求) | 清晰(明确“保留2位小数,按XX方式舍入”) |
| 推荐程度 | 不推荐(存在隐藏异常风险) | 推荐(安全、语义明确) |
永远使用 三参数的 divide 方法(表达式2),显式指定精度和舍入模式,避免依赖默认行为(默认模式 ROUND_UNNECESSARY 几乎不会在实际业务中使用,因为大部分除法运算结果都不精确)。
例如:
BigDecimal result = orderAmt.divide(
BigDecimal.ONE.subtract(feeRatio), // 除数
2, // 保留2位小数
RoundingMode.HALF_UP // 舍入模式(根据业务需求选择)
);
这样既保证了代码的健壮性,又让可读性更强(一看就知道是“保留2位小数的除法”)。
当看到一些不好的代码时,会发现我还算优秀;当看到优秀的代码时,也才意识到持续学习的重要!--buguge
本文来自博客园,转载请注明原文链接:https://www.cnblogs.com/buguge/p/18844473
【从0到1构建一个ClaudeAgent】协作-Agent团队