Search code examples
javarecursionpi

Java: calculate Pi via recursion (if else only)


i have to calculate with this Formula the number Pi. Note: beginner in java. My idea till now:

public static void main(String[] args) {
    System.out.println(Math.sqrt(quadraticFractionSum(20) * 6.0));
}
static double quadraticFractionSum(double counter) {
    if (counter == 1000.0) {
        return counter;
    } else {
        return counter + 1 / (quadraticFractionSum(counter + 1) * quadraticFractionSum(counter + 1));
    }
}

the problem is it takes forever to calculate that :/ - solved: Answers: Alain O'Dea + Balwinder Singh

new problem : the code is not calculating pi - solved answer: Aimert

much appreciated for your help


Solution

  • You have three problems (one possibly minor, non-fatal):

    1. Severe for performance: unnecessary quadratic complexity of recursion
    2. Severe for correctness: You start at the wrong count and the recursive case is wrong
    3. Minor, but instructive: unnecessary use of floating-point and possible rounding errors

    Unnecessary quadratic complexity of recursion


    You recompute the recursion quadratically which is intensely expensive. You're doing 2^980 recursive calls (note I'm talking about individual method invocations not stack depth here) when you only need to do 980. That's a bad cost explosion.

    Start at the wrong count and the recursive case is wrong


    Secondly, you need to start count at 1, not 20 and you need to do 1/counter^2 + quadSum(count+1) in the recursive case. I use 1.0d/counter^2 there to ensure Java uses double arithmetic. Otherwise it would use integral arithmetic and give only 1 or 0 as results.

    The base case (stop approximating at 1000 iterations) should return 1.0d/counter^2 for that last iteration. I chose instead to make the base case iterations + 1 and return 0.0d because I think it is cleaner.

    Unnecessary use of floating-point and possible rounding errors


    Lastly, your base case may not be working due to accumulated floating-point errors.

    == is a risky proposition for double or any floating point number. Precision errors accumulate with every calculation and can easily lead to it not equating to a whole number for your base case.

    counter should be int. Try that and see if it speeds up.

    Proposed solution


    Here is code demonstrating my proposed fix for you:

    public static void main(String[] args) {
        System.out.println(Math.sqrt(quadraticFractionSum(1) * 6.0));
    }
    static double quadraticFractionSum(int counter) {
        if (counter == 1001) {
            return 0.0d;
        } else {
            return 1.0d / (counter * counter) + quadraticFractionSum(counter + 1);
        }
    }