Java 用 2 个小数位舍入 Bigdecimal 值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22609217/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 16:50:06  来源:igfitidea点击:

Rounding Bigdecimal values with 2 Decimal Places

javabigdecimal

提问by sunleo

I want a function to convert Bigdecimal10.12 for 10.12345and 10.13 for 10.12556. But no function is satisfying both conversion in same time.Please help to achieve this.

我想要一个函数来转换Bigdecimal10.12 for 10.1234510.13 for 10.12556. 但是没有任何功能可以同时满足两种转换。请帮助实现这一点。

Below is what I tried.
With value 10.12345:

以下是我尝试过的。
值为 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)

Output :

输出 :

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

With value 10.12556:

值为 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)

Output :

输出 :

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

采纳答案by Florent Bayle

I think that the RoundingModeyou are looking for is ROUND_HALF_EVEN. From the javadoc:

我认为RoundingMode您正在寻找的是ROUND_HALF_EVEN. 从javadoc

Rounding mode to round towards the "nearest neighbor" unless both neighbors are equidistant, in which case, round towards the even neighbor. Behaves as for ROUND_HALF_UP if the digit to the left of the discarded fraction is odd; behaves as for ROUND_HALF_DOWN if it's even. Note that this is the rounding mode that minimizes cumulative error when applied repeatedly over a sequence of calculations.

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

Here is a quick test case:

这是一个快速测试用例:

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

a = a.setScale(2, BigDecimal.ROUND_HALF_EVEN);
b = b.setScale(2, BigDecimal.ROUND_HALF_EVEN);

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

Correctly prints:

正确打印:

10.12
10.13

UPDATE:

更新:

setScale(int, int)has not been recommended since Java 1.5, when enums were first introduced, and was finally deprecated in Java 9. You should now use setScale(int, RoundingMode)e.g:

setScale(int, int)从 Java 1.5 开始不推荐使用枚举,当时首次引入枚举,最终在 Java 9 中被弃用。您现在应该使用setScale(int, RoundingMode)例如:

setScale(2, RoundingMode.HALF_EVEN)

setScale(2, RoundingMode.HALF_EVEN)

回答by Harmlezz

You may try this:

你可以试试这个:

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

OUTPUT:

输出:

10.12

回答by Erwin Bolwidt

Add 0.001first to the number and then call setScale(2, RoundingMode.ROUND_HALF_UP)

0.001先添加号码,然后拨打setScale(2, RoundingMode.ROUND_HALF_UP)

Code example:

代码示例:

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

回答by Arjit

You can call setScale(newScale, roundingMode)method three times with changing the newScale value from 4 to 3 to 2 like

您可以setScale(newScale, roundingMode)通过将 newScale 值从 4 更改为 3 到 2来调用方法三次

First case

第一种情况

    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

Second case

第二种情况

    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