将 Bigdecimal 值舍入 2 位小数

问题描述 投票:0回答:5

我想要一个函数来转换 Bigdecimal

10.12 for 10.12345
10.13 for 10.12556
。 但没有函数可以同时满足这两种转换。请帮助实现这一点。

以下是我尝试过的。
值为 10.12345:

BigDecimal a = new BigDecimal("10.12345");

a.setScale(2, BigDecimal.ROUND_UP)
a.setScale(2, BigDecimal.ROUND_CEILING)
a.setScale(2, BigDecimal.ROUND_DOWN)
a.setScale(2, BigDecimal.ROUND_FLOOR)
a.setScale(2, BigDecimal.ROUND_HALF_DOWN)
a.setScale(2, BigDecimal.ROUND_HALF_EVEN)
a.setScale(2, BigDecimal.ROUND_HALF_UP)

输出:

10.12345::10.13
10.12345::10.13
10.12345::10.12
10.12345::10.12
10.12345::10.12
10.12345::10.12
10.12345::10.12

值为 10.12556:

BigDecimal b = new BigDecimal("10.12556");

b.setScale(2, BigDecimal.ROUND_UP)
b.setScale(2, BigDecimal.ROUND_CEILING)
b.setScale(2, BigDecimal.ROUND_DOWN)
b.setScale(2, BigDecimal.ROUND_FLOOR)
b.setScale(2, BigDecimal.ROUND_HALF_DOWN)
b.setScale(2, BigDecimal.ROUND_HALF_EVEN)
b.setScale(2, BigDecimal.ROUND_HALF_UP)

输出:

10.12556::10.13
10.12556::10.13
10.12556::10.12
10.12556::10.12
10.12556::10.12
10.12556::10.12
10.12556::10.12
java bigdecimal
5个回答
115
投票

我认为您正在寻找的

RoundingMode
ROUND_HALF_EVEN
。来自javadoc

舍入模式向“最近邻居”舍入,除非两个邻居等距,在这种情况下,向偶数邻居舍入。如果丢弃的分数左边的数字是奇数,则行为与 ROUND_HALF_UP 相同;如果是偶数,则其行为与 ROUND_HALF_DOWN 相同。请注意,这是一种舍入模式,可在一系列计算中重复应用时最大限度地减少累积误差。

这是一个快速测试用例:

BigDecimal a = new BigDecimal("10.12345");
BigDecimal b = new BigDecimal("10.12556");

a = a.setScale(2, RoundingMode.HALF_EVEN);
b = b.setScale(2, RoundingMode.HALF_EVEN);

System.out.println(a);
System.out.println(b);

正确打印:

10.12
10.13

更新:

自 Java 1.5 首次引入枚举以来,

setScale(int, int)
就不再被推荐,并最终在 Java 9 中被弃用。您现在应该使用
setScale(int, RoundingMode)
,例如:

setScale(2, RoundingMode.HALF_EVEN)


17
投票

先添加

0.001
至号码,然后拨打
setScale(2, RoundingMode.ROUND_HALF_UP)

代码示例:

public static void main(String[] args) {
    BigDecimal a = new BigDecimal("10.12445").add(new BigDecimal("0.001"));
    BigDecimal b = a.setScale(2, BigDecimal.ROUND_HALF_UP);
    System.out.println(b);
}

2
投票

你可以试试这个:

public static void main(String[] args) {
    BigDecimal a = new BigDecimal("10.12345");
    System.out.println(toPrecision(a, 2));
}

private static BigDecimal toPrecision(BigDecimal dec, int precision) {
    String plain = dec.movePointRight(precision).toPlainString();
    return new BigDecimal(plain.substring(0, plain.indexOf("."))).movePointLeft(precision);
}

输出:

10.12

2
投票

您可以调用

setScale(newScale, roundingMode)
方法三次,并将 newScale 值从 4 更改为 3 再到 2,如

第一个案例

    BigDecimal a = new BigDecimal("10.12345");

    a = a.setScale(4, BigDecimal.ROUND_HALF_UP); 
    System.out.println("" + a); //10.1235
    a = a.setScale(3, BigDecimal.ROUND_HALF_UP); 
    System.out.println("" + a); //10.124
    a = a.setScale(2, BigDecimal.ROUND_HALF_UP);
    System.out.println("" + a); //10.12

第二个案例

    BigDecimal a = new BigDecimal("10.12556");

    a = a.setScale(4, BigDecimal.ROUND_HALF_UP); 
    System.out.println("" + a); //10.1256
    a = a.setScale(3, BigDecimal.ROUND_HALF_UP); 
    System.out.println("" + a); //10.126
    a = a.setScale(2, BigDecimal.ROUND_HALF_UP);
    System.out.println("" + a); //10.13

0
投票

根据文档,

setScale(int, int)
,自从 Java 1.5 首次引入枚举以来,就不再推荐使用:

新的

setScale(int, RoundingMode)
方法应优先使用此旧方法。

它最终在 Java 9 中被弃用。

您应该致电

setScale(2, RoundingMode.HALF_EVEN)
。它使错误检查变得更加简单,因为您不能传入未定义的
enum
,但您当然可以传入未定义的整数模式。

© www.soinside.com 2019 - 2024. All rights reserved.