Reputation: 55
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
Reputation: 21686
You have three problems (one possibly minor, non-fatal):
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
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