calculating pi

Hi everyone, having some real trouble with my work.

It is supposed to be a function that calculates pi to an accuracy specified by the user.

More info:

Specification:
The function called get_pi must return a double precision approximation to pi .

The accuracy of the approximation to pi is to be determined by an argument to
the function. This argument, called accuracy, a double precision value, will be the maximum % error of the approximation. For example, if accuracy = 12.2 then the returned value must be guaranteed to be in the range pi+/-12.2%.

The interface for the function:

double get_pi(double accuracy);

The Implementation:

One method of evaluating pi is to use the fact that tan(pi/4)=1

A power series for arctan(x) is given by

1/4*pi = (x^(2n+1))/(2n+1)

we should be able to write a summing loop to evaluate this series with x=1 that gives us pi/4.

However, how do we deal with the fact that the power series has an infinite number of terms? We need a termination criterion, which depends upon the accuracy demanded.

As we are not doing a maths course here, I suggest that we accept the following
compromise, an error estimate being:
+/- 4*(x^(2n+1))/(2n+1)

THANK YOU VERY MUCH FOR YOUR HELP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
  #include <iostream>
using namespace std;

double get_pi (double accuracy)
{
    double tolerance, series, working, estimated_error, est_pi;
    int n, a;
    n=0;
    a=1;
    tolerance = 100 - accuracy;
    series = (((1^(2*n))+1)/(2*n+1));
    estimated_error = 4*(((1^(2*n))+1)/(2*n+1));
    est_pi = (4*working);

   while (estimated_error>((tolerance/100)*working))
		{
        a=a*-1;
        n++;
        series = series*a;
        working = working+(4*series);
		}

  return (est_pi);
}

int main()
{
    double acc, out;

    cout << "Please enter the percentage accuracy you wish pi to be calculated to:\n";
    cin >> acc;

    out = get_pi(acc);
    cout << "Your value of pi is: " <<out;

   return 0;
}
"^" is not the operator you think it is, it is actually the binary XOR operator, which does some complicated things to bits, which I'm not going to explain here. Also, considering that 1^n = 1, why don't you just ignore those parts and just do the dividing part?
Check your arctan series: http://en.wikipedia.org/wiki/Inverse_trigonometric_functions#Infinite_series

Operator ^ is not power. There is function pow().
thank you very much, I did not know about the ^ operator. Let me have a play
OK, its all compiling fine, and runs, but either just sits there, supposedly stuck in a loop, or returns 0 after the input stage. Watches dosnt seem to give me anything anymore so i cant debug. :(

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
using namespace std;

double get_pi (double accuracy)
{
    double tolerance, series, working, estimated_error, est_pi;
    int n, a;
    n=0;
    a=1;
    tolerance = 100 - accuracy;
    series = ((2)/(2*n+1));
    estimated_error = 4*((2)/(2*n+1));
    est_pi = (4*working);

   while (estimated_error>((tolerance/100)*working))
		{
        a=a*-1;
        n++;
        series = series*a;
        working = working+(4*series);
		}

  return (est_pi);
}

int main()
{
    double acc, out;

    cout << "Please enter the percentage accuracy you wish pi to be calculated to:\n";
    cin >> acc;

    out = get_pi(acc);
    cout << "Your value of pi is: " <<out;

   return 0;
}
Watches dosnt seem to give me anything anymore so i cant debug. :(

You need to get to the bottom of this issue or you will end up asking other people to do your debugging for you :(

Even without a debugger, you could add extra cout statements at strategic points to display the values of important variables. But figuring out how to use your debugger will repay the effort spent generously.
while (estimated_error>((tolerance/100)*working))

integer division issue maybe?

what happens if you use 100.0 instead of 100?
Last edited on
Tried some more editing, still gets stuck after asking for input, dosn't even want to debug past that point. So confused.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <stdio.h>
using namespace std;

double get_pi (double accuracy)
{
    double tolerance, series, working, estimated_error, est_pi;
    int n, a;
    n = 0;
    a = -1;
    working = 0;
    tolerance = (100-accuracy);
    series = ((2)/(2*n+1));
    estimated_error = (4*((2)/(2*n+1)));
    est_pi = (4*working);

   while (estimated_error>((tolerance/100)*working))
		{
        a = (a*-1);
        n++;
        series = (series*a);
        working = (working+(4*series));
		}

  return (est_pi);
}

int main()
{
    double acc, out;

    cout << "Please enter the percentage accuracy you wish pi to be calculated to:\n";
    cin >> acc;

    out = get_pi(acc);
    cout << "Your value of pi is: " <<out;

    return 0;
   }


Thanks everyone for your help so far.
Line 11: working = 0
Line 15: est_pi = 4*working = 4*0 = 0
Line 25: return est_pi (which hasn't been changed, and so will always be 0)
Thanks giblit, your code really helped a lot. Seems like someone else on my course is confused too.

I modified both of ours to achieve:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
#include <stdio.h>
using namespace std;

double get_pi(double accuracy)
{
     double pi = 4.0 , decimal = 1.0;
     double estimated_error, tolerance;
     int n = 0;

     tolerance = (100-accuracy);
     estimated_error = (4*((1)/(2*n+1)));

     while(n>2)
    {
        decimal -= (1.0/(2.0*n+1));
        --n;
        decimal += (1.0/(2.0*n+1));
        --n;
    }

    if(n>0)
        decimal -= (1.0/(2.0*n+1));

    while (estimated_error > ((tolerance/100)*(pi*decimal)))
		{
        n++;
        }

    return(pi*decimal);
}

int main()
{
    double acc, out;

    cout << "Please enter the percentage accuracy you wish 'pi' to be calculated to:\n";
    cin >> acc;

    out = get_pi(acc);
    cout << "Your value of 'pi' is: " <<out;

    return 0;
}


This compiles etc but again seem to get stuck. I know that Line 25-28 is causing the problem. Do i need to put the other loops inside it?
Yes, you do. Otherwise, it is just iterating n without doing anything else. Also, you do realize that your means of approximation will take substantially longer than, say, 4(arctan(1/5) - arctan(1/239)) = pi. The power series still works for this, assuming that you rewrite the x value in each instance to be 1/5 and 1/239. There are better methods, but this will suffice for a "power series" way (unless you want to get into Ramanujan's stuff, but that's a lot to take in. Easier to stick with Machin) unless your teacher allows you to go outside of that method of approximation. Otherwise, just make ist so lines 25-28 encompass the entirety of the actual calculation, and you should be set.
As a start, line 12:

estimated_error = (4*((1)/(2*n+1)));

estimated_error will always be 4.0 since n is zero.

n is initialized to zero on line 9 and hence the while loop on line 14 and the if statement on line 22 can never execute.

The while loop on line 25 is probably an infinite loop (depending on the value of tolerance). The loop will either not execute at all or will execute an infinite amount of times since there is nothing in the body of the loop which will change the loop condition.

As we are not doing a maths course here, I suggest that we accept the following
compromise, an error estimate being:
+/- 4*(x^(2n+1))/(2n+1)


This criteria arises from the mathematical fact that for the power series for arctan(x), the error in truncating the series is less in magnitude than the absolute value of the first term omitted.

You need to sum the series until the next term to be added times 4.0 is <= the desired accuracy. The 4.0 factor arises because arctan( 1 ) is only pi/4.
Last edited on
Thank you to both Ispil and Alrededor.

The calculations were put inside the loop and n is no longer initialised at 0.

This makes it run, but now the output is always stuck at 2.66 until a silly value is entered, then its a small negative decimal.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <stdio.h>
using namespace std;

double get_pi(double accuracy)
{
     double pi = 4.0 , decimal = 1.0;
     double estimated_error, tolerance;
     int n;

     tolerance = (100-accuracy);
     estimated_error = (4*((1)/(2*n+1)));

     while (estimated_error > ((tolerance/100)*(pi*decimal)))
		{
        n++;
        tolerance = (100-accuracy);
        estimated_error = (4*((1)/(2*n+1)));

            while(n>2)
        {
            decimal -= (1.0/(2.0*n+1));
            --n;
            decimal += (1.0/(2.0*n+1));
            --n;
        }

            if(n>0)
            decimal -= (1.0/(2.0*n+1));
        }

    return(pi*decimal);
}

int main()
{
    double acc, out;

    cout << "Please enter the percentage accuracy you wish 'pi' to be calculated to:\n";
    cin >> acc;

    out = get_pi(acc);
    cout << "Your value of 'pi' is: " <<out;

    return 0;
}
update, now have:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <stdio.h>
using namespace std;

double get_pi(double accuracy)
{
     double pi = 4.0 , decimal = 1.0;
     double estimated_error, term;
     int n, z = 1;

     estimated_error = (4.0*((1.0)/double(2*n+1)));

     while (estimated_error > ((accuracy/100.)*(pi*term)))
		{
        n++;
        estimated_error = (4.*((1.0)/double(2*n+1)));
        decimal = (1.0/double(2*n+1));

            /*while(n>2)
        {
            decimal -= (1.0/double(2*n+1));
            --n;
            decimal += (1.0/double(2*n+1));
            --n;
        }

            if(n>0)
            decimal -= (1.0/double(2*n+1));

            */

        term = term+(decimal*double(z));
        z=z*-1;
        cout << pi*term << "\n"; ///shows working

        }

    return(pi*term);
}

int main()
{
    double acc, out;

    cout << "Please enter the percentage accuracy you wish 'pi' to be calculated to:\n";
    cin >> acc;

    while(acc>100 || acc<0) /// Continues to prompt if amount was inputted incorrectly.
		{
			cout << "Please enter a value in the range 0-100, try again: ";
			cin >> acc;
		}

    out = get_pi(acc);
    cout << "Your value of 'pi' is: " <<out;

    return 0;
}


this gets close to what i need in terms of calculation, but it dosnt get close to pi
now you have an undefined value for n so that's even worse than 0. Look at line 11 what is n supposed to be?
Last edited on
Topic archived. No new replies allowed.