BigDecimal金额除法必须显式调用divide方法并指定scale=2和RoundingMode.HALF_UP,否则无限小数会抛ArithmeticException;推荐封装工具方法统一处理。

<p>BigDecimal 做金额除法时保留 2 位小数,关键不是“配置”,而是显式调用 <strong>divide</strong> 方法并指定 <strong>scale</strong> 和 <strong>RoundingMode</strong>。</p>
<H3>必须指定 scale 和 rounding mode</H3>
<p>BigDecimal 的 divide() 默认不接受无限小数(如 1 ÷ 3),会直接抛 <font color="red">ArithmeticException</font>。所以不能只写 <code>bigDec.divide(another)</code>,必须明确:</p>
<ul>
<li><strong>保留几位小数</strong>(scale = 2)</li>
<li><strong>如何处理多余位数</strong>(必须选一个 RoundingMode,推荐 <code>RoundingMode.HALF_UP</code>,即四舍五入)</li>
</ul>
<H3>正确写法示例</H3>
<p>以 100.00 ÷ 3 计算为例:</p>
<pre><code>BigDecimal a = new BigDecimal("100.00");
BigDecimal b = new BigDecimal("3");
BigDecimal result = a.divide(b, 2, RoundingMode.HALF_UP); // 结果为 33.33</code></pre>
<p>注意:<br>
• 第二个参数 <code>2</code> 是 scale(保留 2 位小数)<br>
• 第三个参数是舍入模式,<code>HALF_UP</code> 最符合日常金额习惯(类似数学四舍五入)</p>
<H3>避免常见错误</H3>
<ul>
<li>不要用 <code>setScale(2)</code> 替代 divide 的参数 —— 先 divide 再 setScale 可能因精度丢失引发异常或结果不准</li>
<li>不要传 double 构造 BigDecimal(如 <code>new BigDecimal(0.1)</code>),会带来不可控精度问题;应使用字符串构造,如 <code>new BigDecimal("0.1")</code></li>
<li>如果除数可能为 0,需提前判空或捕获 <code>ArithmeticException</code></li>
</ul>
<H3>封装成工具方法更安全</H3>
<p>项目中建议封装复用:</p>
<pre><code>public static BigDecimal divideMoney(BigDecimal dividend, BigDecimal divisor) {
if (divisor == null || divisor.compareTo(BigDecimal.ZERO) == 0) {
throw new IllegalArgumentException("除数不能为零");
}
return dividend.divide(divisor, 2, RoundingMode.HALF_UP);
}</code></pre>
<p>这样每次调用都统一规则,不易遗漏 scale 和舍入模式。</p>