C++;丘德诺夫斯基π公式 我试图让一个C++应用程序为我计算PI。我试图实施查德诺夫斯基公式,但运气不佳

C++;丘德诺夫斯基π公式 我试图让一个C++应用程序为我计算PI。我试图实施查德诺夫斯基公式,但运气不佳,c++,formula,pi,C++,Formula,Pi,这是我的密码: #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++) { p

这是我的密码:

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

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

您的
fac
函数未正确处理
0
fac(0)
应为
1


3/2
的计算结果为
1
(因为它使用整数除法,它会截断),这使得公式的计算结果完全错误。

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

您的
fac
函数未正确处理
0
fac(0)
应为
1

3/2
计算结果为
1
(因为它使用整数除法,它会截断),这会使您的公式计算结果完全错误。

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

改用这个:

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

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

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

改用这个:

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


此外,您的fac代码也远未达到最佳状态。

您几乎肯定希望对双打进行所有计算,以避免大量耗时的转换。您可能还希望使用
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;
}
#包括
#包括
#包括
双fac(双数值){
双结果=1.0;

对于(double i=2.0;i您几乎肯定希望对double进行所有计算,以避免大量耗时的转换。您可能还希望使用迭代实现的
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;
}
#包括
#包括
#包括
双fac(双数值){
双结果=1.0;

对于(double i=2.0;我你期望什么?实际发生了什么?旁注:Chudnovsky公式收敛速度足够快,你只需要1或2个条件就可以达到
double
@Mysticial的完全精度:看到你对这样的问题发表评论总是让我发笑(;你期望什么?实际发生了什么?旁注:Chudnovsky公式收敛得足够快,实际上只需要1到2个术语就可以达到
双精度
@Mysticial:看到你对这样的问题发表评论总是让我发笑(;如何获得邪恶的长十进制数?@JavaCoder-1337:请参阅
setprecision(15)
。将其计算到该精度,然后只将其打印到5似乎是毫无意义的。我正在尝试让这个程序输出它计算的所有pi。这意味着我需要一个长的十进制。我如何得到它?@JavaCoder-1337:您可以尝试将
双精度
更改为
长双精度
。具体取决于您使用的编译器如果使用,可能会得到大约20位精度(甚至更多)。除此之外,您还需要研究某种扩展精度浮点包。如何获得邪恶的长十进制数?@JavaCoder-1337:请参阅
setprecision(15)
。将其计算到该精度,然后只将其打印到5似乎是毫无意义的。我正在尝试让这个程序输出它计算的所有pi。这意味着我需要一个长的十进制。我如何得到它?@JavaCoder-1337:您可以尝试将
双精度
更改为
长双精度
。具体取决于您使用的编译器如果您使用,可能会得到大约20位精度(甚至更多)。除此之外,您还需要研究某种扩展精度浮点包。