Calculating pi value - what's wrong with my code

I am doing another exercise in C ++. I have to calculate the pi value from an infinite series:

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

The program should print the approximate value of pi after each of the first 1000 members of this series. Here is my code:

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

      

It compiles with no errors or warnings, but after execution only a blank console window appears. If I remove the line "if (i% 1000 == 0)", I see that it starts and prints every pi value, but it doesn't stop, which means the second if statement doesn't work either. I'm not sure what else to do. I guess this is probably a simple logical error.

+2


source to share


10 answers


Well, i% 1000 will never be = 0 since your counter runs from i = 1 and then in increments of 2. Hence, i is always odd and will never be a multiple of 1000.

The reason it never ends is because the algorithm does not converge to exactly 3.14157 - that would be higher precision either below or above the approximation. You want to say "When in the given delta 3.14157", write



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

      

or something similar, since you want to "close" before you stop.

+20


source


Since you start i at 1 and increase by 2, i is always an odd number, so i% 1000 will never be 0.



+7


source


you have several problems:

and. i% 1000 == 0 will never be true because you are only repeating odd numbers.

B. pi == 3.14159: You cannot compare double values ​​in the same way as floating point numbers (you can read about this here in another question). for it to work, you must compare the values ​​differently - one way is to subtract them from each other and check that the absolute result is less than 0.0000001.

+4


source


  • You have floating point issues. Try it if(abs(pi - 3.14159) < 0.000005)

    .
  • i%1000

    will never be 0 because it is i

    always odd.
+2


source


Must not be:

if (counter%1000==0)

      

+2


source


  • i starts at 1 and then increases by 2. So i is always odd and will never be a multiple of 1000, so if (i% 1000 == 0) never gets through.

  • Direct comparison of floats does not work due to floating precision issues. You will need to compare that the difference between the values ​​is close enough.

+2


source


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

Summarizing

pi = .sigma; i = 0& infin; (-1) i 4 / (2 i +1)

Which gives us a cleaner approach to each term; term i 'is defined as follows:

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

      

where i = 0,1,2, ..., N

So, our loop can be pretty simple given some number of iterations 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;
}

      

The original question said, "The program should print out the approximate pi value after each of the first 1000 members of this series." This doesn't mean you need to check if 3.14159 was reached, so I left it out here. The challenge pow(-1,i%2)

is to avoid instructions if

(which are slow) and prevent any complications with a large i .

Remember that after a number of iterations, the difference between pi and the value of the correction term (e.g. -4/25) will be so small that it will be outside the precision limits double

, so you will need higher precision to handle it.

+2


source


By default, abs uses the abs macro, which is for int. For doubles, use the cmath library.

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

      

0


source


Here is the corrected code. I thought it might be useful in the future if anyone has a similar problem.

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

      

0


source


Here's the best option:

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

}

      

0


source







All Articles