0

我对金额有以下要求:

1.2448 -> 1.25
3.349  -> 3.35
0.474  -> 0.47

我已经尝试了BigDecimal的所有可能模式。setScale (2, RoundingMode .) 方法,没有任何成功。结果如下:

UP:        1.25,  3.35,  0.48
HALF_UP:   1.24,  3.35,  0.47
CEILING:   1.25,  3.35,  0.48
FLOOR:     1.24,  3.34,  0.47
DOWN:      1.24,  3.34,  0.47
HALF_DOWN: 1.24,  3.35,  0.47
HALF_EVEN: 1.24,  3.35,  0.47

我也尝试过使用 BigDecimal.round(),结果也不好。

我怎样才能以所需的方式四舍五入?

编辑:

为什么我实际上需要以这种看似奇怪的方式进行舍入?

在我们正在开发的新软件中,我们需要重现舍入行为或遗留软件(这是企业希望进行舍入的方式)

解决方案:

我绝对希望在我的所有计算中都使用 BigDecimals。

所以,最后我想出了这个简单的函数来进行“渐进式”舍入:

public static BigDecimal roundAmount(BigDecimal amount) {
    for (int i = amount.scale(); i >= 2; i--) {
        amount = amount.setScale(i, RoundingMode.HALF_UP);
    }
    return amount;
}
4

4 回答 4

6

使用HALF_UP但首先舍入到小数点后三位,然后再次舍入到 2。问题是您所需的舍入显示不一致的逻辑,因为 1.2448 小于 1.245,因此通常会向下舍入。但是先四舍五入到 3 位将得到 1.245,然后四舍五入到 1.25。

于 2013-01-14T16:12:38.493 回答
1

您正在尝试做的是逐步四舍五入每个数字。1.2448 -> 1.245 -> 1.25。

这意味着需要四舍五入的最小数字是 .nn4444444444444445,这接近于在缩放后添加 1/2 - 4/9,即 1/18。

每当我看到有人建议这是不正确的,但很容易计算。

for (double d : new double[]{1.2448, 3.349, 0.474}) {
    double rounded = Math.round(d * 1e2 + 1.0 / 18) / 1e2;
    System.out.printf("%s should be %.2f rounded half up and is %s%n", d, d, rounded);
}

印刷

1.2448 should be 1.24 rounded half up and is 1.25
3.349 should be 3.35 rounded half up and is 3.35
0.474 should be 0.47 rounded half up and is 0.47

正如您所看到的,需要添加 1/18 是一个奇数,但是当您逐步将每个数字向上取整时,这就是您有效地做的事情。

于 2013-01-14T16:27:11.060 回答
1

这里那里

public static double iterativeRound(double d, int scale) {
    int currentScale = new BigDecimal(String.valueOf(d)).scale();
    while (currentScale >= scale) {
        double i = Math.pow(10, currentScale--);
        d = Math.round(d * i) / i;
    }
    return d;
}

例如:

System.out.println(iterativeRound(1.2448, 2));
System.out.println(iterativeRound(3.349, 2));
System.out.println(iterativeRound(0.474, 2));

印刷:

1.25
3.35
0.47
于 2013-01-14T16:31:44.167 回答
0
public static void main(String[] args) {
    double a = 0.474;

    NumberFormat df = DecimalFormat.getInstance();
    df.setMinimumFractionDigits(2);
    df.setMaximumFractionDigits(3);
    df.setRoundingMode(RoundingMode.HALF_UP);

    double b = Double.valueOf(df.format(a));
    NumberFormat dff = DecimalFormat.getInstance();
    dff.setMaximumFractionDigits(2);
    dff.setRoundingMode(RoundingMode.HALF_UP);

    System.out.println(dff.format(b));

}

试试这个。

于 2013-01-14T16:20:24.227 回答