如何用C ++中的3位小数精度计算pi?

时间:2017-07-11 04:44:02

标签: c++ c++11

嘿伙计们我正在尝试使用这个公式计算pi:  pi = 4·[1 - 1/3 + 1/5 - 1/7 + 1/9 ... +( - 1)^ n /(2n + 1)] 但我总是得到一个零输出pi值,我真的很困惑,我出错了。这是我的代码:

#include <cmath>
#include <iostream>
using namespace std;
int main()
{
    int n;
    double b = 0;
    char c = 'Y';
    int s = 1;
    while (c == 'Y') {
        cout << "Enter the value of the parameter 'n' in the Leibniz formula (or -1 to quit):" << endl;
        cin >> n;
        if (n != -1) {
            c = 'Y';

            for (int a = 1; a <= n; a++) {
                s = -s;
                b += 4 * (s/ (2 * a + 1));
            }

            cout << "The approximate value of pi using 1 term is:" << b << endl;
        }

        else {
            c = 'N';
        }
    }



    return 0;
}

4 个答案:

答案 0 :(得分:2)

在C和C ++中,对整数的数学运算产生一个整数,即使结果在传统数学中是分数的。将您的int更改为floatdouble,我怀疑它会更好用。

结果是截断为整数值并且具有整数类型。

例如:2 / 4会产生05 / 2会产生2

注意如果在浮点值和整数值之间执行操作,则结果为浮点值。所以:

2.0 / 4 == 0.5

答案 1 :(得分:2)

您的代码似乎很复杂,int类型用于需要浮动操作的地方。

考虑以下简化示例:

#include <cmath>
#include <iostream>
using namespace std;
int main()
{
    int n = 0;
    double b = 0;

    double s = 1;  // Tytpe is changed
    while (n != -1) {  // there is no need for char c
        cout << "Enter the value of the parameter 'n' in the Leibniz formula (or -1 to quit):" << endl;
        cin >> n;
        b = 0; // init b before starting the loop
        s = 1; // the same for s (it can be -1 from the next user input)
        // there is no need for  if (n != -1) because for has condition
        for (int a = 1; a <= n; a++) {
                s = -s;
                b += 4 * (s / (2.0 * a + 1));
        }
        cout << "The approximate value of pi using 1 term is:" << b << endl;
    }

    return 0;
}

重要更新:

为了使您的计算正确(根据Leibniz's formula),我建议在for循环中进行以下更改:

    for (int a = 0; a <= n; a+=2) { // start from 0 with step 2
          b += 4.0 * (s / (a + 1.0));
          s = -s; // change the sign for next calculation
    }

并且进一步考虑某种优化

    b = 0; // do not forget about reseting b to 0 before making sum
    s = 1; // set 1 in the sign
    for (int a = 0; a <= n; a+=2) { // start from 0 with step 2
            b += s / (a + 1.0); // no multiplication on each iteration
            s = -s; // because s was initialized with 1
    }
    b *= 4.0; // multiply once for the whole sum

更新2

如果精确度对于输出非常重要,最终片段可以是:

#define _USE_MATH_DEFINES
#include <cmath>
#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
    int n = 0;
    double b = 0;
    double s = 1;
    int prec = 0;
    cout << "What precision should be used for output? (Value from 1 to 10): ";
    while (prec< 1 || prec > 10)
    {
        cin >> prec;
    }
    while (true) {
        cout << "Enter the value of the parameter 'n' in the Leibniz formula (or -1 to quit):" << endl;
        cin >> n;
        if (n == -1)
        {
            break; // go out the loop if user enter -1 (want to exit)
        }
        else if (n <= 0)
        {
            cout << "'n' have to be 1 or greater" << endl;
            continue; // go to the next iteration to ask new 'n'
        }
        s = 1; 
        b = 1.0; // we can start from 1 (no need to claculate the first term) and make loop from 2
        for (int a = 2; a < n*2; a+=2) { // start from 2 with step 2 (so n should be doubled)
            s = -s; // change the sign for this iteration, because now loop started from a = 2
            b += s / (a + 1.0); 
        }
        b *= 4.0;
        cout << "The approximate value of pi using 1 term is: " << setprecision(prec+1) << b << " (PI = " << M_PI << ")" << endl;
    }
    return 0;
}

注意:

在此版本b中使用1.0初始化,因为Leibniz系列中的第一项始终为1(我们可以跳过计算,但我们应该更改符号更改的逻辑 - make {{1}或者在求和之前移动s = -1; - 我选择第二个选项)。

此外,我不确定&#34;参数&#39; n&#39;在Leibniz公式&#34;中,所以要注意s = -s;循环的条件 - 现在(使用for)如果a < n*2是Leibniz系列中的项目数,那么它是正确的计算。

答案 2 :(得分:1)

除了进行整数数学运算外,还有其他一些小问题。

首先,公式为[1 - ...],而非[0 - ...],因此您需要将b初始化为1.0,而不是0

其次,它应该是4 * [...],但是你在循环的每次迭代中乘以4,所以你得到`[0 - b 1 * 4 + b 2 * 4 -b 3 * 4 ....]。

如果你愿意,你可以 分配乘法,但如果你这样做,你需要正确地分配它(例如,起始值1.0也需要乘以4)。

另请注意,您没有正确重新初始化,因此在您尝试重新计算该值的第二次(以及后续次)时,您将获得完全错误的答案(直到您修复更多内容)。

答案 3 :(得分:0)

你被整数分裂焚烧了。

b += 4 * (s/ (2 * a + 1));

a是一个int,因此除法结果是一个int。 施法者加倍将修复它:

b += 4 * (s/ (2 * double(a) + 1));