roundingmode.unnecessary要求计算结果必须精确,否则抛出arithmeticexception;适用于整除、已知精度匹配等确定场景,误用会导致运行时异常。

RoundingMode.UNNECESSARY 的作用是:要求计算结果必须精确,不能有任何舍入。只要运算结果无法用指定精度精确表示,就会直接抛出 ArithmeticException —— 它不是“不处理舍入”,而是“拒绝任何需要舍入的场景”。
明确哪些操作会触发异常
以下情况会立即抛出 ArithmeticException:
- 除法结果为无限小数(如
10.divide(new BigDecimal("3"), 2, RoundingMode.UNNECESSARY)) - setScale() 指定的小数位数少于当前精度且需丢弃非零数字(如
new BigDecimal("1.234").setScale(2, RoundingMode.UNNECESSARY)) - 乘法或加减后超出目标精度且末尾有非零数字(取决于 scale 和值)
正确使用 UNNECESSARY 的前提
它只适用于你完全确定结果可精确表示的场景,比如:
- 整数间的除法,且被除数能被除数整除(
new BigDecimal("100").divide(new BigDecimal("4"), RoundingMode.UNNECESSARY)✅) - 已知小数位数一致的数值缩放(
new BigDecimal("5.00").setScale(1, RoundingMode.UNNECESSARY)❌——因为 5.00 → 5.0 是截断,但末尾零不影响值,实际可行;而"5.01".setScale(1, ...)就会失败) - 业务规则保证数据格式(如金额单位为分,全部用整数运算,不涉及除法)
替代方案:安全兜底或主动校验
如果不确定是否精确,不要硬用 UNNECESSARY,可选:
-
先试算再捕获:用 try-catch 包裹,捕获
ArithmeticException后降级处理(如改用 HALF_UP 或报业务错误) -
预先判断是否可整除:对除法,用
remainder(divisor).signum() == 0确认余数为零再调用 UNNECESSARY - 换用更稳妥的模式:如 RoundingMode.HALF_UP + 显式声明精度,配合业务校验逻辑
常见误用与修复示例
错误写法:
BigDecimal price = new BigDecimal("19.99");BigDecimal vat = price.multiply(new BigDecimal("0.2")).setScale(2, RoundingMode.UNNECESSARY); // 可能失败
原因:19.99 × 0.2 = 3.998,保留 2 位小数需舍入 → 抛异常。
修复方式:
- 改用
RoundingMode.HALF_UP(最常用) - 或先确保输入可控:用
new BigDecimal("1999").multiply(new BigDecimal("20")).divide(new BigDecimal("1000"))(整数运算,避免小数误差)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











