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


88

我需要以下结果

100.12 -> 100.00
100.44 -> 100.00
100.50 -> 101.00
100.75 -> 101.00

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

Answers:


150

您可以使用setScale()将小数位数减少为零。假设value拥有要取整的值:

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

使用起来round()有点麻烦,因为它要求您指定要保留的位数。在您的示例中,该值为3,但这不适用于所有值:

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

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


1
它不起作用:100.12:100.12,100.44:100.44,100.50:100.5,100.75:100.75
BorisPavlović10年

3
不,设置比例会返回一个新的小数,该小数与第一个小数不相同。例如:BigDecimal bd1 = new BigDecimal(100.12); BigDecimal bd2 = bd1.setScale(0, RoundingMode.HALF_UP); System.out.println(bd1.equals(bd2));打印错误
Daniel Fath

6
@Daniel:我已经在答案中发布的代码段中已经暗示了这一点。我现在已经明确了。
Grodriguez 2010年

RoundingMode那是什么?这是BigDecimal
三部曲


10

如果我听格罗德里格斯的回答

System.out.println("" + value);
value = value.setScale(0, BigDecimal.ROUND_HALF_UP);
System.out.println("" + value);

这是输出

100.23 -> 100
100.77 -> 101

这不是我想要的,所以我最终这样做了。

System.out.println("" + value);
value = value.setScale(0, BigDecimal.ROUND_HALF_UP);
value = value.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("" + value);

这就是我得到的

100.23 -> 100.00
100.77 -> 101.00

暂时解决了我的问题.. ::谢谢大家。


7
我对第一个结果“不是我想要的...”的说法感到好奇。如果您实际上关心输出格式,则可以使用DecimalFormat(如中的new DecimalFormat("###.00"))来管理BigDecimal返回到字符串的转换。它给出"101.00"了@Grodriquez和您创建的片段的两个值的结果。
joel.neely

3
由于您已经知道已经有一个整数,因此第二次在这里进行舍入是不必要的,因此我将使用BigDecimal.ROUND_UNNECESSARY来代替,我认为这会更清楚一些。
kosmoplan

5

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

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

测试代码:

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());
}

输出:

100
100
101
101


不认可此解决方案或其他任何方法,但是input.toBigInteger().toString().length()使用对数(例如round_up(log(input)) + (1 if input is a power of ten, else 0)
Addison,


0

我认为您无法在单个命令中像这样四舍五入。尝试

    ArrayList<BigDecimal> list = new ArrayList<BigDecimal>();
    list.add(new BigDecimal("100.12"));
    list.add(new BigDecimal("100.44"));
    list.add(new BigDecimal("100.50"));
    list.add(new BigDecimal("100.75"));

    for (BigDecimal bd : list){
        System.out.println(bd+" -> "+bd.setScale(0,RoundingMode.HALF_UP).setScale(2));
    }

Output:
100.12 -> 100.00
100.44 -> 100.00
100.50 -> 101.00
100.75 -> 101.00

我为您的其余示例进行了测试,它返回了所需的值,但我不保证其正确性。


-2

你要

round(new MathContext(0));  // or perhaps another math context with rounding mode HALF_UP

2
这什么也没做。在文档中round:“如果精度设置为0,则不进行舍入。”
Grodriguez 2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.