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が、最初は小数点以下 3 桁に丸め、次に再度 2 に丸めます。問題は、1.2448 が 1.245 より小さいため、通常は切り捨てられるため、目的の丸めが一貫性のないロジックを示すことです。ただし、最初に 3 桁に丸めると 1.245 になり、次に 1.25 に丸められます。

于 2013-01-14T16:12:38.493 に答える
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 に答える
1

あなたがやろうとしているのは、各桁を徐々に丸めることです。1.2448 -> 1.245 -> 1.25。

これは、切り上げに必要な最小数が .nn4444444444444445 であることを意味します。これは、1/18 であるスケーリング後に 1/2 - 4/9 を追加することに近いです。

誰かがこれを提案するのを見たときはいつでも、それは間違っていましたが、計算するのは簡単です.

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

ご覧のとおり、18 分の 1 を足す必要があるのは奇数ですが、各桁を徐々に切り上げていくと効果的です。

于 2013-01-14T16:27:11.060 に答える
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 に答える