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)。
- 要是5后面全是0,就直接舍弃(比如
为什么你的代码里两种模式输出一致?
先看你贴的代码:
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
相关产品推荐
相关产品推荐

