6

このアルゴリズムを実装するコードを作成しています。

方式

ただし、MathContext(1000) を使用しても、このエラーが発生します。

Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
at java.math.BigDecimal.divide(BigDecimal.java:1603)
at picalculator.PiCalculator.calculatePi(PiCalculator.java:59)
at picalculator.PiCalculator.main(PiCalculator.java:25)
Java Result: 1

この方法を使用している間:

public static void calculatePi() {
    BigInteger firstFactorial;
    BigInteger secondFactorial;
    BigInteger firstMultiplication;
    BigInteger firstExponent;
    BigInteger secondExponent;
    int firstNumber = 1103;
    BigInteger firstAddition;
    BigDecimal currentPi = BigDecimal.ONE;
    BigDecimal pi = BigDecimal.ONE;
    BigDecimal one = BigDecimal.ONE;
    int secondNumber = 2;
    double thirdNumber = Math.sqrt(2.0);
    int fourthNumber = 9801;
    BigDecimal prefix = BigDecimal.ONE;

    for(int i=1;i<4;i++){
        firstFactorial = factorial(4*i);
        secondFactorial = factorial(i);
        firstMultiplication = BigInteger.valueOf(26390*i);
        firstExponent = exponent(secondFactorial, 4);
        secondExponent = exponent(BigInteger.valueOf(396),4*i);
        firstAddition = BigInteger.valueOf(firstNumber).add(firstMultiplication);
        currentPi = currentPi.add(new BigDecimal(firstFactorial.multiply(firstAddition)).divide(new BigDecimal(firstExponent.multiply(secondExponent)), new MathContext(10000)));
    }

    prefix =new BigDecimal(secondNumber*thirdNumber);
    prefix = prefix.divide(new BigDecimal(fourthNumber), new MathContext(1000));

    currentPi = currentPi.multiply(prefix, new MathContext(1000));

    pi = one.divide(currentPi);

    System.out.println("Pi is: " + pi);

    return;
}

factorial(a); であることを証明しました。と exponent(a,b) はそれぞれ a の階乗と a^b の結果を正確に返します。

これを修正する方法を知っている人はいますか?

4

2 に答える 2

5

あなたが必要

pi = one.divide(currentPi, new MathContext(1000));

結果はほぼ確実に 10 進数の繰り返しになるためです。

検討

BigDecimal a = new BigDecimal("4");
BigDecimal b = new BigDecimal("3");

BigDecimal c = a.divide(b)                         // java.lang.ArithmeticException: Non-terminating decimal expansion
BigDecimal c = a.divide(b, new MathContext(10));   // No exception
于 2012-03-20T04:29:32.073 に答える
3

別のバージョンのdivideを使用することをお勧めします。これにより、返されるBigDecimalの最終的なスケールをより細かく制御できます。一方、ご使用のバージョンでは、最終的なスケールは被除数と除数のスケールによって異なります。

int scale = 3;
BigDecimal result = ONE.divide(new BigDecimal("3"), scale, RoundingMode.HALF_UP);
// result is 0.333
于 2012-03-20T09:05:57.000 に答える