我在做的另一个C++的运动。我必须计算出的价值pi从无限的系列:

pi=4 - 4/3 + 4/5 – 4/7 + 4/9 -4/11+ ...

该程序具有打印的近似值pi后每1 000名第一的条件的这个系列。这里是我的代码:

#include <iostream>
using namespace std;

int main()
{
    double pi=0.0;
    int counter=1;

    for (int i=1;;i+=2)//infinite loop, should "break" when pi=3.14159
    {
        double a=4.0;
        double b=0.0;

        b=a/static_cast<double>(i);

        if(counter%2==0)
            pi-=b;
        else
            pi+=b;

        if(i%1000==0)//should print pi value after 1000 terms,but it doesn't  
            cout<<pi<<endl;

        if(pi==3.14159)//this if statement doesn't work as well
            break;

        counter++;
    }

    return 0;
}

它汇编了没有错误和警告,但只有在空窗口控制台后出现的执行。如果我删除线"如果(i%1000==0)",我可以看到它并运行和印刷每pi的价值,但它不会停止,这意味着第二,如果声明的不能工作。我不知道还能做些什么。我假设它可能是一个简单的逻辑错误。

有帮助吗?

解决方案

好,则i%千永远= 0,作为违背从i = 1,则在2。因此增量,i是总是奇数,并且永远不会为1000的倍数。

它从不终止的原因是,该算法不收敛于准确3.14157 - 这将是一个更高的精度或者下方或上方的近似。你想说“的3.14157给定的三角形内当”,所以写

if (fabs(pi - 3.14157) < 0.001)
  break

或类似的,但是为“关闭”你想让你停止之前的东西。

其他提示

由于你在1和增量2启动I,I始终是一个奇数,所以我%1000将永远不会为0。

在有一个以上的问题:

一个。我因为你只迭代奇数%1000 == 0永远是正确的。

B中。 PI == 3.14159:你不能比较的双精度值就这样,因为浮点数字所代表的方式(你可以在这里另外一个问题读到它)。为了使它工作,你应该以另一种方式比较值 - 。一个办法是彼此相减,并检查绝对结果比0.0000001较低

  1. 你有点浮动的精确度问题。尝试 if(abs(pi - 3.14159) < 0.000005).
  2. i%1000 不会因为0 i 总是奇数。

它不应该是:

if (counter%1000==0)
  1. 我从1开始,然后递增2。因此,我总是奇数,并将永远是一个多的1000,这就是为什么如(i%1000==0)从来没有通过。

  2. 直接比较浮动不起作用,由于漂浮的精确度问题。你将需要比较,将差值之间是足够接近。

PI = 4 - 4/3 4/5 + - + 4/7 4/9 -4/11 + ...

要概括

PI =Σ<子>的 I = 0 (-1) I 4 /(2 I 的1)

这使我们对每个术语的清洁器的方法;所述的 I 的'个项由下式给出:

double term = pow(-1,i%2) * 4 / (2*i+1);

,其中 I 的= 0,1,2,...,N

因此,我们的环可以是相当简单的,给定的一些迭代次数N个

int N=2000;
double pi=0;
for(int i=0; i<N; i++)
{
    double term = pow(-1,i%2) * 4 / (2*(double)i+1);
    pi += term;
    cout << i << "\t" << pi <<endl;
}

您原来的问题指出,“该方案具有每个这种系列的第一千个术语的后打印pi的近似值”。这并不意味着任何需要检查是否3.14159已达到,所以我没有将这个在这里。所述pow(-1,i%2)呼叫是只是为了避免if语句(其是慢),并防止任何并发症大的 I

注意,迭代次数,pi的大小和修正项的大小(比如-4/25)之间的差额后,将是如此之小,它会超越一个double的精度,所以你将需要更高的精度类型来处理它。

默认情况下ABS采用ABS宏这是对于int。双打中,使用CMATH库。

#include <iostream>
#include <cmath>

int main()
{
    double pi=0.0;

    double a=4.0;
    int i = 1; 

    for (i=1;;i+=2)
    {

        pi += (1 - 2 * ((i/2)%2)) * a/static_cast<double>(i);          

        if( std::abs(pi - 3.14159) < 0.000001 )
              break;

        if (i > 2000) //1k iterations
              break;
    }

    std::cout<<pi<<std::endl;

    return 0;
}

下面是校正代码。我想这可能是有益的,今后如果有人有类似的问题。

#include <iostream>
#include <cmath>

using namespace std;

int main()
{
double pi=0.0;
int counter=1;

for (int i=1;;i+=2)
{
 double a=4.0;
 double b=0.0;

 b=a/static_cast<double>(i);

 if(counter%2==0)
  pi-=b;
 else
  pi+=b;

 if(counter%1000==0) 
  cout<<pi<<" "<<counter<<endl;


 if (fabs(pi - 3.14159) < 0.000001) 
  break;

 counter++;
}
cout<<pi;

 return 0;
}

下面是一个更好的:

class pi_1000
{
public:
    double doLeibniz( int i ) // Leibniz famous formula for pi, source: Calculus II :)
    {
        return ( ( pow( -1, i ) ) * 4 ) / ( ( 2 * i ) + 1 );
    }

 void piCalc()
{
    double pi = 4;
    int i;

    cout << "\npi calculated each iteration from 1 to 1000\n"; //wording was a bit confusing.
                                                    //I wasn't sure which one is the right one: 0-1000 or each 1000th.
    for( i = 1; i < 1000; i++ )
    {
        pi = pi + doLeibniz( i );
        cout << fixed << setprecision( 5 ) << pi << "\t" << i + 1 << "\n";
    }

    pi = 4;
    cout << "\npi calculated each 1000th iteration from 1 to 20000\n";
    for( i = 1; i < 21000; i++ )
    {
        pi = pi + doLeibniz( i );
        if( ( ( i - 1 ) % 1000 )  == 0 )
            cout << fixed << setprecision( 5 ) << pi << "\t" << i - 1 << "\n";
    }

}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top