计算C ++中π的Leibniz求和的迭代次数

时间:2016-03-12 12:52:38

标签: c++ loops pi

我的任务是询问用户他们希望迭代总和与pi的实际值相比多少小数位。因此当循环达到3.14时,2个小数位将停止。我有一个完整的程序,但我不确定它是否真的按预期工作。我用计算器检查了0和1小数位,它们似乎工作,但我不想假设它适用于所有这些。此外,我的代码可能有点笨拙,因为仍在学习基础知识。我们只学习了循环和嵌套循环。如果有任何明显的错误或部分可以清理,我将不胜感激。 编辑:我只需要将此工作最多五位小数。这就是我的pi值不精确的原因。很抱歉对于这个误会。

#include <iostream>
#include <cmath>
using namespace std;

int main() {

const double PI = 3.141592;
int n, sign = 1;
double sum = 0,test,m;

cout << "This program determines how many iterations of the infinite series   for\n"
        "pi is needed to get with 'n' decimal places of the true value of pi.\n"
        "How many decimal places of accuracy should there be?" << endl;
cin >> n;

double p = PI * pow(10.0, n);
p = static_cast<double>(static_cast<int>(p) / pow(10, n));
int counter = 0;
bool stop = false;

for (double i = 1;!stop;i = i+2) {
    sum = sum + (1.0/ i) * sign;
    sign = -sign;
    counter++;
    test = (4 * sum) * pow(10.0,n);
    test = static_cast<double>(static_cast<int>(test) / pow(10, n));

        if (test == p)
            stop = true;
}
cout << "The series was iterated " << counter<< " times and reached the value of pi\nwithin "<< n << " decimal places." << endl;
return 0;
}

2 个答案:

答案 0 :(得分:0)

您的程序永远不会终止,因为test==p永远不会成立。这是两个计算方式不同的双精度数字之间的比较。由于舍入错误,它们将不相同,即使您运行无限次迭代,并且您的数学是正确的(现在它不是,因为您的程序中PI的值是不准确)。

为了帮助您弄清楚发生了什么,请在每次迭代中打印test的值,以及testpi之间的距离,如下所示:

#include<iostream>
using namespace std;

void main() {
    double pi = atan(1.0) * 4; // Make sure you have a precise value of PI
    double sign = 1.0, sum = 0.0;
    for (int i = 1; i < 1000; i += 2) {
        sum = sum + (1.0 / i) * sign;
        sign = -sign;
        double test = 4 * sum;
        cout << test << " " << fabs(test - pi) << "\n";
    }
}

确保程序正常运行后,最终根据testpi之间的距离更改停止条件。

for (int i=1; fabs(test-pi)>epsilon; i+=2)

答案 1 :(得分:0)

Leibniz求和的一个问题是它具有极低的收敛速度,因为它表现出次线性收敛。在你的程序中,你还将计算出的π与给定值(6位数近似值)进行比较,而求和点应该是找出正确的数字。

如果想要的数字在迭代之间没有变化(我还添加了最大迭代次数检查),您可以稍微修改您的代码以使其终止计算。请记住,您使用的double不是无限制的精确数字,迟早的舍入误差会影响计算。事实上,这段代码的真正局限在于它所需的迭代次数(2,428,700,925获得3.141592653)。

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

using std::cout;

// this will take a long long time...
const unsigned long long int MAX_ITER = 100000000000;

int main() {

    int n;

    cout << "This program determines how many iterations of the infinite series for\n"
            "pi is needed to get with 'n' decimal places of the true value of pi.\n"
            "How many decimal places of accuracy should there be?\n";
    std::cin >> n;

    // precalculate some values
    double factor = pow(10.0,n);
    double inv_factor = 1.0 / factor;
    double quad_factor = 4.0 * factor;

    long long int test = 0, old_test = 0, sign = 1;
    unsigned long long int count = 0;
    double sum = 0;

    for ( long long int i = 1; count < MAX_ITER; i += 2 ) {
        sum += 1.0 / (i * sign);
        sign = -sign;
        old_test = test;
        test = static_cast<long long int>(sum * quad_factor);
        ++count;
        // perform the test on integer values
        if ( test == old_test ) {
            cout << "Reached the value of Pi within "<< n << " decimal places.\n";
            break;          
        }
    } 

    double pi_leibniz = static_cast<double>(inv_factor * test);
    cout << "Pi = " << std::setprecision(n+1) << pi_leibniz << '\n';    
    cout << "The series was iterated " << count << " times\n";

    return 0;
}

我已在此表中总结了几次运行的结果:

digits        Pi           iterations
---------------------------------------
 0        3                           8
 1        3.1                        26
 2        3.14                      628
 3        3.141                   2,455
 4        3.1415                136,121
 5        3.14159               376,848
 6        3.141592            2,886,751
 7        3.1415926          21,547,007
 8        3.14159265        278,609,764
 9        3.141592653     2,428,700,925
10        3.1415926535   87,312,058,383