1

我正在尝试让 C++ 应用程序为我计算 pi。我试图实施 Chudnovsky 公式但没有运气。

这是我的代码:

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

这样做的目的是让程序输出 Chudnovsky 公式的 10 次迭代。相反,我得到了这个:

call of overloaded `pow(int, long int&)' is ambiguous 
4

3 回答 3

8

您从不初始化pi,因此您的代码具有未定义的行为。

您的fac函数无法正确处理0fac(0)应该是1)。

3/2评估为1(因为它使用整数除法,它会截断),这会使您的公式评估为完全错误的答案。

于 2012-08-19T17:07:10.137 回答
4

你几乎肯定想在双打上做所有的数学运算,以避免大量浪费时间的转换。您可能还想使用迭代实现fac而不是递归实现(并不是说递归会成为一个问题,但这是一个很好的例子,说明何时应该真正避免递归,因为它不会给您带来任何好处)。当然,您还需要pi像其他人已经指出的那样进行初始化。

#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;
}
于 2012-08-19T17:28:28.277 回答
1

pow(-1, k) 无效,因为它是从数学公式到代码的直接转换。

改用这个:

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

编辑:

此外,您的 fac 代码也远非最佳。

于 2012-08-19T17:21:07.793 回答