关于BigDecimal的除法运算,注意2个表达式 :`orderAmt.divide(divisor).setScale(2, roundingMode)` 与 `orderAmt.divide(divisor, 2, roundingMode)`

BigDecimal的除运算,主要有下面3个重载:

  • BigDecimal divide(BigDecimal divisor)
  • BigDecimal divide(BigDecimal divisor, RoundingMode roundingMode)
  • BigDecimal divide(BigDecimal divisor, int scale, RoundingMode roundingMode)

关于orderAmt.divide(divisor).setScale(2, roundingMode)orderAmt.divide(divisor, 2, roundingMode) ,这两个表达式的核心区别在于 是否在除法操作时明确指定精度和舍入模式,以及可能引发的行为差异。

一. 表达式1orderAmt.divide(divisor).setScale(2, roundingMode)

  • 执行过程
  1. 先调用 divide(BigDecimal divisor) 进行除法运算,未指定精度(scale)和舍入模式,此时会使用 默认舍入模式BigDecimal.ROUND_UNNECESSARY)。
  2. 如果除法结果无法精确表示(例如除不尽),divide() 会直接抛出 ArithmeticException(因为默认模式要求结果必须精确)。
    异常stacktrace:
java.lang.ArithmeticException: 
Non-terminating decimal expansion; no exact representable decimal result.
	at java.math.BigDecimal.divide(BigDecimal.java:1707)
  1. 若未抛出异常,再通过 setScale(2, roundingMode) 对结果进行精度调整,使用指定的 roundingMode 舍入到 2 位小数。
  • 风险
    若除法结果不精确(如 1 ÷ 3),第一步 divide() 会直接报错,无法进入 setScale 步骤。

二. 表达式2orderAmt.divide(divisor, 2, roundingMode)

  • 执行过程
    直接调用 divide(BigDecimal divisor, int scale, RoundingMode roundingMode) 三参数重载方法,在除法运算的同时指定精度(2位小数)和舍入模式

    • 无论除法结果是否精确,都会按照指定的 scaleroundingMode 进行舍入,不会抛出异常(除非除数为 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位小数的除法”)。

常见舍入模式:

  • RoundingMode.HALF_UP:四舍五入(最常用)。
  • RoundingMode.DOWN:直接截断,不进位。
  • RoundingMode.UP:无论尾数是否为 0,都进位(例如 0.333 保留 2 位为 0.34)。

来源链接:https://www.cnblogs.com/buguge/p/18844473

© 版权声明
THE END
支持一下吧
点赞5 分享
评论 抢沙发
头像
请文明发言!
提交
头像

昵称

取消
昵称表情代码快捷回复

    暂无评论内容