2012-03-20 16 views
6

estoy elaboración de código para implementar este algoritmo:no terminación decimal error incluso con MathContext

formula

Sin embargo, estoy recibiendo este error, incluso con 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 

Durante el uso de este método:

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

he demostrado que facto rial (a); y el exponente (a, b) devuelve el factorial de a y el resultado de a^b respectivamente, con precisión.

¿Alguien sabe cómo solucionar esto?

Respuesta

5

Usted necesita

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

Como el resultado es casi seguro que un decimal periódico.

Considere

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

¡Gracias, funciona ahora! Sin embargo, no estoy obteniendo el resultado que había planeado, no parece estar implementando el algoritmo correctamente. – Toby

3

Es posible que prefiera utilizar versión diferente de divide. Le da más control sobre la escala final del BigDecimal devuelto. Mientras que, con su versión, la escala final depende de la escala del dividendo y el divisor.

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