Java BigDecimal:舍入到最接近的整数值

n a*_*n a 84 java rounding bigdecimal

我需要以下结果

100.12 -> 100.00
100.44 -> 100.00
100.50 -> 101.00
100.75 -> 101.00
Run Code Online (Sandbox Code Playgroud)

.round()还是.setScale()?我该怎么做?

Gro*_*uez 142

您可以使用setScale()将小数位数减少到零.假设value保持要舍入的值:

BigDecimal scaled = value.setScale(0, RoundingMode.HALF_UP);
System.out.println(value + " -> " + scaled);
Run Code Online (Sandbox Code Playgroud)

使用round()更复杂,因为它要求您指定要保留的位数.在您的示例中,这将是3,但这对所有值都无效:

BigDecimal rounded = value.round(new MathContext(3, RoundingMode.HALF_UP));
System.out.println(value + " -> " + rounded);
Run Code Online (Sandbox Code Playgroud)

(请注意,BigDecimal对象是不可改变的,既setScaleround,会返回一个新的对象)

  • @Daniel:我在回答中发布的代码片段已经暗示了这一点.我现在已经明确了. (6认同)
  • 不,设置比例会返回与第一个不同的新小数.例如:`BigDecimal bd1 = new BigDecimal(100.12); BigDecimal bd2 = bd1.setScale(0,RoundingMode.HALF_UP); System.out.println(bd1.equals(bd2));`打印为false (3认同)

n a*_*n a 10

如果我按照格罗德里格斯的回答

System.out.println("" + value);
value = value.setScale(0, BigDecimal.ROUND_HALF_UP);
System.out.println("" + value);
Run Code Online (Sandbox Code Playgroud)

这是输出

100.23 -> 100
100.77 -> 101
Run Code Online (Sandbox Code Playgroud)

这不是我想要的,所以我最终做到了这一点..

System.out.println("" + value);
value = value.setScale(0, BigDecimal.ROUND_HALF_UP);
value = value.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("" + value);
Run Code Online (Sandbox Code Playgroud)

这就是我得到的

100.23 -> 100.00
100.77 -> 101.00
Run Code Online (Sandbox Code Playgroud)

这解决了我现在的问题.. :)谢谢大家.

  • 我很好奇第一个结果"不是我想要的......"的说法.如果你真的关心输出格式化,你可以使用`DecimalFormat`(如`new DecimalFormat("###.00")`)来管理`BigDecimal`转换回字符串.它给出了"101.00"作为两个值的结果,来自@Grodriquez和你创建的片段. (7认同)
  • 你第二次在这里舍入是不必要的,因为你知道你已经有了一个整数,所以我会使用BigDecimal.ROUND_UNNECESSARY,在我看来更清楚一点. (3认同)

Sea*_*oyd 5

这是一个非常复杂的解决方案,但它的工作原理:

public static BigDecimal roundBigDecimal(final BigDecimal input){
    return input.round(
        new MathContext(
            input.toBigInteger().toString().length(),
            RoundingMode.HALF_UP
        )
    );
}
Run Code Online (Sandbox Code Playgroud)

测试代码:

List<BigDecimal> bigDecimals =
    Arrays.asList(new BigDecimal("100.12"),
        new BigDecimal("100.44"),
        new BigDecimal("100.50"),
        new BigDecimal("100.75"));
for(final BigDecimal bd : bigDecimals){
    System.out.println(roundBigDecimal(bd).toPlainString());
}
Run Code Online (Sandbox Code Playgroud)

输出:

100
100
101
101