Question

I am trying to make a C++ application calculate pi for me. I have tried to implement the Chudnovsky formula with no luck.

Here is my code:

#include <iostream>
#include <cmath>

long fac(long num) {
    if (num == 1)
        return 1;
    return fac(num - 1) * num;
}

int main() {
    using namespace std;
    double pi;
    for (long k = 0; k < 10; k++) {
        pi += (pow(-1, k) * fac(6 * k) * (13591409 + (545140134 * k))) / (fac(3 * k) * pow(fac(k), 3) * pow(640320, 3 * k + 3/2));
    }
    pi *= 12;
    cout << 1 / pi << endl;
    system("pause");
    return 0;
}

The goal of this was to have the program output 10 iterations of the Chudnovsky formula. Instead, I got this:

call of overloaded `pow(int, long int&)' is ambiguous 
Was it helpful?

Solution

You never initialize pi, so your code has undefined behaviour.

Your fac function does not correctly handle 0 (fac(0) should be 1).

3/2 evaluates to 1 (because it uses integer division, which truncates), and this makes your formula evaluate to the completely wrong answer.

OTHER TIPS

You almost certainly want to do all the math on doubles, to avoid lot of time-killing conversions. You probably also want to use an iterative implementation of fac instead of a recursive one (not that recursion is going to be a big problem, but this is a prime example of when recursion should really be avoided because it gains you nothing). Of course you also need to initialize pi as others have already pointed out.

#include <iostream>
#include <iomanip>
#include <cmath>

double fac(double num) {
    double result = 1.0;
    for (double i=2.0; i<num; i++)
       result *= i;
    return result;
}

int main() {
    using namespace std;
    double pi=0.0;
    for (double k = 0.0; k < 10.0; k++) {
        pi += (pow(-1.0,k) * fac(6.0 * k) * (13591409.0 + (545140134.0 * k))) 
            / (fac(3.0 * k) * pow(fac(k), 3.0) * pow(640320.0, 3.0 * k + 3.0/2.0));
    }
    pi *= 12.0;
    cout << setprecision(15) << 1.0 / pi << endl;
    return 0;
}

pow(-1, k) is ineffective as it is a direct translation from math formula to the code.

Use this instead:

      (k%2==1?-1.0:1.0)*fac(...

Edit:

Also your fac code is far from optimal too.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top