571

次のコードで以下に示す例外が発生するのはなぜですか?

BigDecimal a = new BigDecimal("1.6");
BigDecimal b = new BigDecimal("9.2");
a.divide(b) // results in the following exception.

例外:

java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
4

9 に答える 9

955

Java 11BigDecimalドキュメントから:

0 の精度設定でオブジェクトが提供された場合MathContext(たとえば、 )、オブジェクトMathContext.UNLIMITEDを取らない算術メソッドと同様に、算術演算は正確です。MathContext(これは、5 より前のリリースでサポートされていた唯一の動作です。)

正確な結果を計算する結果として、MathContext精度設定が 0 のオブジェクトの丸めモード設定は使用されないため、無関係です。除算の場合、正確な商は無限に長い小数展開を持つ可能性があります。たとえば、1 を 3 で割った値です。

商が終わらない 10 進展開を持ち、演算が正確な結果を返すように指定されている場合、anArithmeticExceptionがスローされます。それ以外の場合は、他の演算と同様に、除算の正確な結果が返されます。

修正するには、次のようにする必要があります

a.divide(b, 2, RoundingMode.HALF_UP)

ここで、2 はスケールで、RoundingMode.HALF_UP は丸めモードです。

詳細については、このブログ投稿を参照してください。

于 2011-01-04T06:37:35.633 に答える
83

精度と丸めモードを指定していないためです。BigDecimal は、10、20、5000、または無限の小数点以下の桁数を使用できると不平を言っていますが、それでも数値を正確に表現することはできません。そのため、間違った BigDecimal を提供する代わりに、単にあなたを怒らせます。

ただし、RoundingMode と精度を指定すると、変換できます (たとえば、1.333333333-to-infinity を 1.3333 のようなものに変換できます...ただし、プログラマーとして、「満足している精度」を伝える必要があります)。 '。

于 2011-01-04T06:39:55.833 に答える
70

できるよ

a.divide(b, MathContext.DECIMAL128)

必要なビット数を選択できます: 32、64、または 128 のいずれかです。

このリンクをチェックしてください:

http://edelstein.pebbles.cs.cmu.edu/jadeite/main.php?api=java6&state=class&package=java.math&class=MathContext

于 2013-03-06T02:49:26.870 に答える
3

BigDecimalに対する回答が ArithmeticException をスローする

public static void main(String[] args) {
        int age = 30;
        BigDecimal retireMentFund = new BigDecimal("10000.00");
        retireMentFund.setScale(2,BigDecimal.ROUND_HALF_UP);
        BigDecimal yearsInRetirement = new BigDecimal("20.00");
        String name = " Dennis";
        for ( int i = age; i <=65; i++){
            recalculate(retireMentFund,new BigDecimal("0.10"));
        }
        BigDecimal monthlyPension =   retireMentFund.divide(
                yearsInRetirement.divide(new BigDecimal("12"), new MathContext(2, RoundingMode.CEILING)), new MathContext(2, RoundingMode.CEILING));      
        System.out.println(name+ " will have £" + monthlyPension +" per month for retirement");
    }
public static void recalculate (BigDecimal fundAmount, BigDecimal rate){
        fundAmount.multiply(rate.add(new BigDecimal("1.00")));
    }

分割メソッド呼び出しに MathContext オブジェクトを追加し、精度と丸めモードを調整します。これで問題が解決するはずです

于 2016-06-20T16:53:22.923 に答える
1

私にとっては、これで動作しています:

BigDecimal a = new BigDecimal("9999999999.6666",precision);
BigDecimal b = new BigDecimal("21",precision);

a.divideToIntegralValue(b).setScale(2)
于 2021-02-05T01:14:08.047 に答える