2012-03-20 36 views
6

我各具特色的代碼來實現這個算法:非終止十進制錯誤甚至MathContext的

formula

不過,我得到這個錯誤,即使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; 
} 

我已經證明了事實里亞爾(一);和指數(a,b)分別準確地返回a的階乘和a^b的結果。

有誰知道如何解決這個問題?

回答

5

你需要

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

因爲結果幾乎肯定是一個循環小數。

考慮

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 
+0

謝謝,它現在可行!但是,我沒有得到我計劃的結果,它似乎沒有正確實施算法。 – Toby 2012-03-20 16:01:07

3

你可能更喜歡使用的divide不同的版本。它使您可以更好地控制返回的BigDecimal的最終比例。鑑於您的版本,最終的規模取決於股息和除數的規模。

int scale = 3; 
BigDecimal result = ONE.divide(new BigDecimal("3"), scale, RoundingMode.HALF_UP); 
// result is 0.333