6

重複の可能性:
BigDecimal.divide 中に ArithmeticException がスローされる

これにより、ArithmeticException が発生します: http://ideone.com/RXeZw

スケールと丸めモードを提供すると、間違った結果が得られます。この例では、50.03% が出力されるはずです。これを正しく丸めるには?

簡単に参照できるように、これはコードです。

BigDecimal priceDiff = BigDecimal.ONE
     .subtract(new BigDecimal(9.99)
     .divide(new BigDecimal(19.99)))
     .multiply(new BigDecimal(100));
System.out.println(priceDiff.toPlainString());
4

5 に答える 5

10

BigDecimal.divide(BigDecimal divisor)結果を正確に表すことができない場合、ArithmeticException をスローします。
これを処理する方法を伝える MathContext または RoundingMode を使用する必要があります。例えば:

public class Test {
    public static void main(String[] args) throws java.lang.Exception {
        BigDecimal priceDiff = BigDecimal.ONE.subtract(new BigDecimal("9.99").divide(new BigDecimal("19.99"), MathContext.DECIMAL128))
                                             .multiply(new BigDecimal(100));
        System.out.println(priceDiff.toPlainString());
    }
}

作品と版画

50.0250125062531265632816408204102100

また、リテラルを使用して作成する場合の問題を回避するために、BigDecimal(String)コンストラクターの使用にも注意してください。BigDecimaldouble

于 2012-08-29T12:39:01.890 に答える
4

無限の小数として除算として MathContext を使用する必要があります。

    BigDecimal priceDiff = BigDecimal.ONE
            .subtract(new BigDecimal(9.99)
            .divide(new BigDecimal(19.99), new MathContext(10, RoundingMode.UP)))
            .multiply(new BigDecimal(100));
    System.out.println(priceDiff.toPlainString());

ただし、それは 50.025... を出力します。

これは 49.98 を出力します:

BigDecimal priceDiff = new BigDecimal(9.99)
        .divide(new BigDecimal(19.99), new MathContext(10, RoundingMode.UP))
        .multiply(new BigDecimal(100), new MathContext(4, RoundingMode.UP));
System.out.println(priceDiff.toPlainString());
于 2012-08-29T12:39:15.693 に答える
2

Javadocから:

除算の場合、正確な商は無限に長い小数展開を持つ可能性があります。たとえば、1 を 3 で割った値です。商の 10 進展開が終了せず、演算が正確な結果を返すように指定されている場合、ArithmeticException がスローされます。

MathContext解決策は、たとえば、部門にを提供することMathContext.DECIMAL128です。丸めを従来の方法 (最も近い偶数ではなく半分に丸める) で行う場合は、以下を使用します。MathContext(int precision)

また、引数ではなく引数を使用してBigDecimals を作成する必要があります。後者は精度が失われるためです。Stringdouble

于 2012-08-29T12:44:15.193 に答える
1

@Keppilの答えに似ています

double d = (1 - 9.99 / 19.99) * 100;
System.out.printf("%.2f%%%n", d);

版画

50.03%

これは方程式の答えではないため、49.98% を得ることはできません。

于 2012-08-29T12:43:33.293 に答える
1

BigDecimal 操作は、常に正確な結果を計算しようとします。これを試して。

 BigDecimal priceDiff = BigDecimal.ONE
                .subtract(new BigDecimal(9.99)
                        .divide(new BigDecimal(19.99),RoundingMode.HALF_UP))
                .multiply(new BigDecimal(100));
        System.out.println(priceDiff.toPlainString());
于 2012-08-29T12:42:20.547 に答える