RoundingMode.HALF_DOWN 是“小数部分≤0.5向下舍入、>0.5向上舍入”,恰好符合标准“五舍六入”定义;它不是按个位数字判断,而是基于小数部分与0.5比较,且必须用字符串构造 BigDecimal 以避免浮点误差。

RoundingMode.HALF_DOWN 实际上并不是“五舍六入”,而是“四舍五入,但 0.5 向下舍入”,也就是常说的“银行家舍入法”的变体之一(注意:它和 RoundingMode.HALF_EVEN 不同)。很多人误以为 HALF_DOWN 是“五舍六入”,其实是对语义的误解。
HALF_DOWN 的真实规则
HALF_DOWN 的定义是:
- 小数部分 小于 0.5 → 向下舍入(即舍去)
- 小数部分 大于 0.5 → 向上舍入(即进一)
- 小数部分 等于 0.5 → 向下舍入(即舍去)
例如:
2.5 → 2(0.5 向下舍)
3.5 → 3
1.4 → 1
1.6 → 2
为什么不是“五舍六入”?
“五舍六入”是一个特定的业务规则(如上海出租车计价),它的逻辑是:
- 小数部分 ≤ 0.5 → 舍(如 2.5 → 2)
- 小数部分 > 0.5 → 入(如 2.6 → 3)
这看起来和 HALF_DOWN 很像,但关键区别在于:HALF_DOWN 对 0.5 是向下舍,而“五舍六入”中的“五舍”也向下舍——二者在 0.5 行为上一致。所以严格来说,HALF_DOWN 恰好符合“五舍六入”的舍入边界定义(即以 0.5 为分界,≤0.5 舍、>0.5 入)。
立即学习“Java免费学习笔记(深入)”;
⚠️ 注意:“五舍六入”这个说法容易让人误以为“5 就舍,6 就入”,但实际是看小数部分是否超过 0.5,不是看个位数字。BigDecimal 处理的是十进制小数,不是整数末位。
正确使用 HALF_DOWN 的代码示例
要实现标准的“五舍六入”(即 ≤0.5 舍、>0.5 入),直接用 HALF_DOWN 即可:
BigDecimal bd = new BigDecimal("2.5");
BigDecimal rounded = bd.setScale(0, RoundingMode.HALF_DOWN); // 结果:2
bd = new BigDecimal("2.51");
rounded = bd.setScale(0, RoundingMode.HALF_DOWN); // 结果:3
常见误区:
- 不要用 double 构造 BigDecimal(如
new BigDecimal(2.5)),会因二进制浮点误差导致意外结果,应使用字符串构造 - setScale 的 scale 参数表示保留的小数位数,设为 0 表示取整
如果真需要“整数末位五舍六入”(非标准小数舍入)
极少数场景(如老式手工计费)可能要求按个位数字判断:个位是 5 就舍、6 就入。这不是 BigDecimal 的职责,需自行拆解:
- 转成字符串,定位小数点后第一位
- 若为 '5' → 舍;若 ≥ '6' → 入;否则按常规处理
- 这种逻辑不属于 HALF_DOWN,也不推荐混用,应单独封装
标准金融或科学计算中,“五舍六入”指的就是 HALF_DOWN 所定义的小数舍入行为。


















