2012-03-20 11 views
6

mam umacnianie kod do realizacji tego algorytmu:niekończący dziesiętny Błąd Nawet MathContext

formula

Jednak dostaję ten błąd, nawet z 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 

Podczas korzystania z tej metody:

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; 
} 

I dowiodły, że facto rial (a); a wykładnik potęgny (a, b) zwraca odpowiednio silnię i wynik odpowiednio^b.

Czy ktoś wie, jak to naprawić?

Odpowiedz

5

Trzeba

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

Ponieważ wynik jest prawie na pewno ułamek dziesiętny nieskończony.

Rozważmy

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

Dzięki, działa już teraz! Jednak nie osiągam rezultatu, na który się zdecydowałem, nie wydaje się, żeby właściwie wdrażał algorytm. – Toby

3

może wolisz używać innej wersji divide. Daje ci większą kontrolę nad ostateczną skalą zwracanego BigDecimal. Natomiast w Twojej wersji ostateczna skala zależy od skali dywidendy i dzielnika.

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