2012-03-20 35 views
6

Tôi crafting mã để thực hiện thuật toán này:Không Ngừng Decimal Lỗi Thậm chí Với MathContext

formula

Tuy nhiên, tôi nhận được lỗi này, ngay cả với 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 

Trong khi sử dụng phương pháp này:

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

tôi đã chứng minh rằng trên thực tế rial (a); và số mũ (a, b) trả về giai thừa của a và kết quả của^b tương ứng, chính xác.

Có ai biết cách sửa lỗi này không?

Trả lời

5

Bạn cần

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

Kể từ khi kết quả là gần như chắc chắn một số thập phân lặp lại.

Cân nhắc

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

Cảm ơn, nó hoạt động ngay bây giờ! Tuy nhiên, tôi không nhận được kết quả mà tôi đã lên kế hoạch cho, doen't nó dường như đang thực hiện các thuật toán đúng cách. – Toby

3

Bạn có thể thích sử dụng phiên bản khác của divide. Nó cho phép bạn kiểm soát nhiều hơn quy mô cuối cùng của BigDecimal đã trả về. Trong khi đó, với phiên bản của bạn quy mô cuối cùng phụ thuộc vào quy mô của cổ tức và số chia.

int scale = 3; 
BigDecimal result = ONE.divide(new BigDecimal("3"), scale, RoundingMode.HALF_UP); 
// result is 0.333 
Các vấn đề liên quan