Click here to Skip to main content
15,444,353 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
This is a simple code, but an if statement is not working, and I have no idea why?
The code is easy and is correct, yet the if is not working.



#include <iostream>

using namespace std;


int main()
{


  int how_many_terms=0,one_time=0;
	int counter = 1;
	double odd = 1;
	
	double sum = 0;
	int max = 200000;

	bool bSign = true;

	double pi = 0;
	//4-(4/3)+(4/5)-(4/7)+(4/9)-(4/11)+...

	do {
        		if(bSign)
        		{	
        			pi += 4 / odd;//FIRST ODD IS ONE MAKING THIS A WHOLE NUMBER AS IN JUST 4
        			bSign = false;
        		}
        		else
        		{
        			pi -= 4 / odd;//FIRST ODD IS ONE MAKING THIS A WHOLE NUMBER AS IN JUST 4
        			bSign = true;
        		}
		
    odd+=2;//NEXT ODD NUMBER WE STARTED IN 1 PLUS 2 WE HAVE A SERIES OF ODD NUMBERS



/* ********************** the if below does not work ************************    */
   

 

   if(pi == 3.14159 && one_time==0)// we check when pi has the desired value
   {

      how_many_terms = counter;//we asign the iteration which is the same number of the amount of terms so we know the amount of terms in variable how_many_terms

     // we change the value of one_time so that the condition is no longer true and we only catch the first time pi is 3.14159, which would be the amount oif terms needed for getting the value of  3.14159 for the first time
     
      one_time=999;
    }

    
		counter++; //this increases each cycle in order to count the amount of cycles, of interations
		sum += pi;// TO ADD UP ALL VALUES TO CALCULATE AVERAGE
cout <<" PI SO FAR    "<< pi <<"   times       " <<counter <<endl;		
   
		
	} while ( counter < max );


  //WE CALCULATE AVERAGE HERE 
	cout << "PI : " << (sum / counter) <<" This many terms we need to get the 3.14159  "<<how_many_terms<< endl;
	return 0;
}


What I have tried:

I have changed the code in a lot of different ways, but the if just doesn't work
Posted
Updated 28-Feb-22 20:04pm
Comments
jeron1 28-Feb-22 20:02pm     CRLF
Comparing doubles can be tricky, take a look at, https://www.tutorialspoint.com/what-is-the-most-effective-way-for-float-and-double-comparison-in-c-cplusplus For a way to method to compare.
Love and Hope 28-Feb-22 21:49pm     CRLF
Thanks alot indeed, finally it is working, look: #include <iostream> #include <cmath> #include <limits>using namespace std; /* epsilon function to compare double */ bool cmpf(double A, double B, double epsilon = 0.000005f)/* we set the precision to our needs here*/ { return (fabs(A - B) < epsilon); } int main() { int how_many_terms=0,one_time=0; int counter = 1; double odd = 1; double sum = 0; int max = 200000; bool bSign = true; double pi = 0; //4-(4/3)+(4/5)-(4/7)+(4/9)-(4/11)+... do { if(bSign) { pi += 4 / odd;//FIRST ODD IS ONE MAKING THIS A WHOLE NUMBER AS IN JUST 4 bSign = false; } else { pi -= 4 / odd;//FIRST ODD IS ONE MAKING THIS A WHOLE NUMBER AS IN JUST 4 bSign = true; } odd+=2;//NEXT ODD NUMBER WE STARTED IN 1 PLUS 2 WE HAVE A SERIES OF ODD NUMBERS double desired_pi = 3.14159; counter++; //this increases each cycle in order to count the amount of cycles, of interations sum += pi;// TO ADD UP ALL VALUES TO CALCULATE AVERAGE cout <<" PI SO FAR "<< pi <<" times " <
Rick York 28-Feb-22 22:40pm     CRLF
That is a rather low precision value for pi. You can get a better one by including math.h and preceding it by defining _USE_MATH_DEFINES : #define _USE_MATH_DEFINES #include <math.h> const double desired_pi = M_PI;
Love and Hope 28-Feb-22 22:54pm    
I totally agree with you, but this is for school the teacher wanted it to be done like that, I guess she wanted us to stumble upon double comparison

Floating point numbers aren't accurate.

You can try dividing one by N, in the next line multiply again by N, and check for 1.
It may fail for N=3 or N=10 or many others, as 1/3 and 1/10 cannot be represented exactly in binary floating point notation. 1/2, 1/4, 1/8 can, but 1/3, 1/5, 1/10 can't.

Note: even when (1.0/3.0)*3.0 may be printed as 1, that does not mean it is exactly one; the convert-to-string routines are somewhat 'forgiving'.

Therefore, you should not apply an equality test to floating point numbers, instead allow for some tolerance, as in:
if (abs(currentValue-expectedValue) < epsilon ) ...
where epsilon is some small value, i.e. small with respect to expectedValue.

Note2: if you make epsilon too small, your algorithm may never converge... and that is what you are experiencing right now, as your code basically has epsilon equal to zero.


PS: all of the above applies to all languages I know, it is not specific to C++.
 
Share this answer
 
v6
Comments
Love and Hope 28-Feb-22 21:48pm    
Thanks a lot indeed, I found the solution, the code is working look is pretty much what you and jeron1
Love and Hope 28-Feb-22 21:49pm     CRLF
#include <iostream> #include <cmath> #include <limits>using namespace std; /* epsilon function to compare double */ bool cmpf(double A, double B, double epsilon = 0.000005f)/* we set the precision to our needs here*/ { return (fabs(A - B) < epsilon); } int main() { int how_many_terms=0,one_time=0; int counter = 1; double odd = 1; double sum = 0; int max = 200000; bool bSign = true; double pi = 0; //4-(4/3)+(4/5)-(4/7)+(4/9)-(4/11)+... do { if(bSign) { pi += 4 / odd;//FIRST ODD IS ONE MAKING THIS A WHOLE NUMBER AS IN JUST 4 bSign = false; } else { pi -= 4 / odd;//FIRST ODD IS ONE MAKING THIS A WHOLE NUMBER AS IN JUST 4 bSign = true; } odd+=2;//NEXT ODD NUMBER WE STARTED IN 1 PLUS 2 WE HAVE A SERIES OF ODD NUMBERS double desired_pi = 3.14159; counter++; //this increases each cycle in order to count the amount of cycles, of interations sum += pi;// TO ADD UP ALL VALUES TO CALCULATE AVERAGE cout <<" PI SO FAR "<< pi <<" times " <
CPallini 1-Mar-22 2:12am    
5.
Quote:
If not working with PI calculation

As told, the problem is that floating point values are never exact values.
try this change to see what is going on.
C++
cout << "PI so far: " << pi << " Delta " << pi-3.14159 << endl;
if (pi == 3.14159 && one_time == 0)

A solution is:
C++
if ( abs(pi-3.14159) < 0.00001 && one_time == 0)


Advice: Learn to indent properly your code, it show its structure and it helps reading and understanding. It also helps spotting structures mistakes.
C++
#include <iostream>

using namespace std;

int main() {

    int how_many_terms = 0, one_time = 0;
    int counter = 1;
    double odd = 1;

    double sum = 0;
    int max = 200000;

    bool bSign = true;

    double pi = 0;
    //4-(4/3)+(4/5)-(4/7)+(4/9)-(4/11)+...

    do {
        if (bSign) {
            pi += 4 / odd; //FIRST ODD IS ONE MAKING THIS A WHOLE NUMBER AS IN JUST 4
            bSign = false;
        } else {
            pi -= 4 / odd; //FIRST ODD IS ONE MAKING THIS A WHOLE NUMBER AS IN JUST 4
            bSign = true;
        }

        odd += 2; //NEXT ODD NUMBER WE STARTED IN 1 PLUS 2 WE HAVE A SERIES OF ODD NUMBERS

        /* ********************** the if below does not work ************************    */

        if (pi == 3.14159 && one_time == 0) // we check when pi has the desired value
        {

            how_many_terms = counter; //we asign the iteration which is the same number of the amount of terms so we know the amount of terms in variable how_many_terms

            // we change the value of one_time so that the condition is no longer true and we only catch the first time pi is 3.14159, which would be the amount oif terms needed for getting the value of  3.14159 for the first time

            one_time = 999;
        }

        counter++; //this increases each cycle in order to count the amount of cycles, of interations
        sum += pi; // TO ADD UP ALL VALUES TO CALCULATE AVERAGE
        cout << " PI SO FAR    " << pi << "   times       " << counter << endl;

    } while (counter < max);

    //WE CALCULATE AVERAGE HERE 
    cout << "PI : " << (sum / counter) << " This many terms we need to get the 3.14159  " << how_many_terms << endl;
    return 0;
}

Indentation style - Wikipedia[^]
Best C++ Formatter and Beautifier[^]
Online C/C++ Formatter, Indenter and Beautifier – Techie Delight[^]

Professional programmer's editors have this feature and others ones such as parenthesis matching and syntax highlighting.
Notepad++ Home[^]
ultraedit[^]
Enabling Open Innovation & Collaboration | The Eclipse Foundation[^]
 
Share this answer
 
Comments
CPallini 1-Mar-22 2:12am    
5.
Patrice T 1-Mar-22 2:17am    
Thank you
 
Share this answer
 
Comments
Patrice T 1-Mar-22 2:06am    
+5
CPallini 1-Mar-22 2:11am    
Thank you.
#include <iostream>
#include <cmath>
#include <limits>
using namespace std;

/*

epsilon function to compare double 

*/

bool cmpf(double A, double B, double epsilon = 0.000005f)/* we set the precision to our needs here*/
{
    return (fabs(A - B) < epsilon);
}



int main() {



  int how_many_terms=0,one_time=0;
	int counter = 1;
	double odd = 1;
	
	double sum = 0;
	int max = 200000;


	bool bSign = true;

	double pi = 0;
	//4-(4/3)+(4/5)-(4/7)+(4/9)-(4/11)+...

	do {
        		if(bSign)
        		{	
        			pi += 4 / odd;//FIRST ODD IS ONE MAKING THIS A WHOLE NUMBER AS IN JUST 4
        			bSign = false;
        		}
        		else
        		{
        			pi -= 4 / odd;//FIRST ODD IS ONE MAKING THIS A WHOLE NUMBER AS IN JUST 4
        			bSign = true;
        		}
		
    odd+=2;//NEXT ODD NUMBER WE STARTED IN 1 PLUS 2 WE HAVE A SERIES OF ODD NUMBERS

double desired_pi = 3.14159;
    

 
    
		counter++; //this increases each cycle in order to count the amount of cycles, of interations
		sum += pi;// TO ADD UP ALL VALUES TO CALCULATE AVERAGE
cout <<" PI SO FAR    "<< pi <<"   times       " <<counter <<endl;		




  if(cmpf(desired_pi,pi) && one_time==0)// we check when pi has the desired value
   {

      how_many_terms = counter;//we asign the iteration which is the same number of the amount of terms so we know the amount of terms in variable how_many_terms

     // we change the value of one_time so that the condition is no longer true and we only catch the first time pi is 3.14159, which would be the amount oif terms needed for getting the value of  3.14159 for the first time
     
      one_time=999;
    }







    
		
	} while ( counter < max );


  //WE CALCULATE AVERAGE HERE 
	cout << "AVERAGE PI : " << (sum / counter) <<" This many terms we need to get the 3.14159 : "<<how_many_terms<< endl;
	return 0;
}
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900