manonmars
manonmars

Reputation: 55

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

Upvotes: 2

Views: 763

Answers (2)

Alain O'Dea
Alain O'Dea

Reputation: 21686

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

Upvotes: 3

Aimert
Aimert

Reputation: 146

public static void main(String[] args) {
    System.out.println(Math.sqrt(quadraticFractionSum(1) * 6));
}

static double quadraticFractionSum(int counter) {
    if (counter == 1000) {
        return 1d / (counter * counter);
    } else {
        double quadraticFractionSum = quadraticFractionSum(counter + 1);
        return quadraticFractionSum + 1d / (counter * counter);
    }
}

when you do 1 / whatever, it's giving you an integer result because both numbers are integers. You have to specify you want a double result, otherwise you get zeroes (hence the "1d").

Upvotes: 1

Related Questions