You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中RoundingMode.HALF_DOWN与HALF_UP的差异及输出相同原因咨询

Java中RoundingMode.HALF_DOWN与HALF_UP的区别及代码结果一致的原因

先说说两种舍入模式的核心区别

  • RoundingMode.HALF_UP:就是我们日常说的「四舍五入」——当要舍弃的部分的最高位数字≥5时,就给前一位进1;如果<5则直接舍弃。比如2.35保留1位小数,会得到2.4。
  • RoundingMode.HALF_DOWN:可以理解为「五舍六入」的进阶版——只有当要舍弃的部分的最高位数字>5时才进1;如果等于5,还要看后面有没有非零数字:
    • 要是5后面全是0,就直接舍弃(比如2.35保留1位小数会得到2.3);
    • 要是5后面还有非零数字,那还是要进1(比如2.351保留1位小数会得到2.4)。

为什么你的代码里两种模式输出一致?

先看你贴的代码:

public class BigDecimalDemo { 
    public static void main(String[] args) { 
        BigDecimal bd2=BigDecimal.valueOf(11); 
        BigDecimal bd3=new BigDecimal("2.3"); 
        BigDecimal bdDiv = bd2.divide(bd3,38,RoundingMode.HALF_UP); 
        System.out.println(bdDiv); 
        BigDecimal bdDivDOWN = bd2.divide(bd3,10, RoundingMode.HALF_DOWN); 
        System.out.println(bdDivDOWN); 
        BigDecimal bdDivUP = bd2.divide(bd3,10, RoundingMode.HALF_UP); 
        System.out.println(bdDivUP); 
    } 
}

对应的输出:

4.78260869565217391304347826086956521739
4.7826086957
4.7826086957

我们来拆解计算逻辑:11 ÷ 2.3的精确值是一个无限不循环小数,从你输出的38位结果能看到,小数点后第10位是6,第11位开始是521739...。当我们保留10位小数时:

  • 对于HALF_UP:第11位是5,满足≥5的条件,所以把第10位的6进成7,得到4.7826086957。
  • 对于HALF_DOWN:第11位是5,但后面跟着21739...这些非零数字,触发了「等于5但后面有非零数字则进1」的规则,所以同样把第10位的6进成7,结果和HALF_UP完全一致。

简单说,只有当要舍弃的部分恰好是5且后面没有任何非零数字时,两种模式才会产生不同的结果。比如你可以试试计算BigDecimal.valueOf(2.35).setScale(1, RoundingMode.HALF_UP)和setScale(1, RoundingMode.HALF_DOWN),就能看到明显的差异了。

内容的提问来源于stack exchange,提问作者Jim Huang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 10:47:46