Computing pi to nth terms?

K

Kraig

Hi! I'm new to programming and am trying to figure out the best way
using loops, to compute pi to say, 14 terms using values that double
each time through the loop. As in, from 1-2-4-8-16, et al. I'm at a
loss as to where to start. Does anyone have any ideas how to do this?
Thanks for any help you can provide.

kraig
 
J

John Harrison

Kraig said:
Hi! I'm new to programming and am trying to figure out the best way using
loops, to compute pi to say, 14 terms using values that double each time
through the loop. As in, from 1-2-4-8-16, et al. I'm at a loss as to
where to start. Does anyone have any ideas how to do this? Thanks for any
help you can provide.

kraig

What are you having trouble with, the formula, or how to program it?

If you are having trouble with the formula then that's a math question, try
in sci.math.

If its the programming then why not repeat the formula for those who are
less good a math then you. This will increase you chances of getting an
answer.

Note that this group does not do homework unless you have made some effort
yourself, so show us what you have done so far.

If you really are at a loss where to start and haven't programmed a single
line of code yet then I suggest that you start on a simpler task. Forget
about pi and write a program that uses a loop to output the terms 1 2 4 8 16
32 etc. 14 numbers in all. If you can't manage that then maybe programming
is not for you.

john
 
O

osmium

"Kraig" write:

Any time you can provide an explicit number, such as 14 above, it is an
indicator that the solution will most likely include a for statement in some
fashion.
 
G

George

Kraig said:
Hi! I'm new to programming and am trying to figure out the best way using
loops, to compute pi to say, 14 terms using values that double each time
through the loop. As in, from 1-2-4-8-16, et al. I'm at a loss as to
where to start. Does anyone have any ideas how to do this? Thanks for any
help you can provide.

kraig

#define PI 3.14159

double total = 0;
unsigned char i;

for(i=0; i<14; i++)
total *= PI;
 
G

George

George said:
#define PI 3.14159

double total = 0;
unsigned char i;

for(i=0; i<14; i++)
total *= PI;

but then, that would result in total == 0.

maybe double total = PI:

you will have to finish the assignment yourself sir.

regards
 
K

Kraig

That's where I got lost, on the #define part. I had, to no avail:

#include <iostream>
#include <cmath>
using namespace std;

int main()
{
float fCalcPI = 0;
float fTerms = 0;

cout << "Enter number of terms.\n";
cin >> fTerms;

fCalcPI = fTerms - (fTerms/3) + (fTerms/5) - (fTerms/7) + (fTerms/9) -
(fTerms/11);

cout << "Pi is " << fCalcPI << " \n";

return 0;
}

Like I said, I'm learning as I go. Please be patient :)

kraig
 
J

John Harrison

Kraig said:
That's where I got lost, on the #define part. I had, to no avail:

#include <iostream>
#include <cmath>
using namespace std;

int main()
{
float fCalcPI = 0;
float fTerms = 0;

cout << "Enter number of terms.\n";
cin >> fTerms;

fCalcPI = fTerms - (fTerms/3) + (fTerms/5) - (fTerms/7) + (fTerms/9) -
(fTerms/11);

cout << "Pi is " << fCalcPI << " \n";

return 0;
}

Like I said, I'm learning as I go. Please be patient :)

kraig

Well I can see a few problems here. Firstly you are not using a loop, but
the problem you have to solve is 'the best way using loops, to compute pi to
say, 14 terms using values that double each time through the loop'. Clearly
you must use a loop somewhere.

Secondly you code does nothing like calculate PI. I still don't know what
the formula is that you are trying to use (if I did I would be able to help
you better). But look at what you wrote

cout << "Enter number of terms.\n";
cin >> fTerms;
fCalcPI = fTerms - (fTerms/3) + (fTerms/5) - (fTerms/7) + (fTerms/9) -
(fTerms/11);

Suppose I entered 14 as the number of terms, then the calculation would be

fCalcPI = 14 - (14/3) + (14/5) - (14/7) + (14/9) - (14/11);

which is nothing at all like the correct value of PI.

For the number of terms you want something like this

cout << "Enter number of terms.\n";
int fTerms;
cin >> fTerms;
for (int i = 0; i < fTerms; ++i)
{
...
}

See? That is a loop, and the program will go round the loop the same number
of times as the number of terms that the user entered. You have to fill in
the ... part (and a bit more). I would imagine (but I don't know this
formula) that you need to sum some series. So each time around the loop you
add another term to a total, something like this

float fTotal = 0;
cout << "Enter number of terms.\n";
int fTerms;
cin >> fTerms;
for (int i = 0; i < fTerms; ++i)
{
fTotal += ...;
}

Again you've still got to fill in the ... part. And I'm guessing here, it
might be that the formula you have in mind is completely different.

Also note that fTerms is an integer. For some reason you have declared it as
a float. But the number of terms must be an integer, you cannot have half a
term!

john
 
K

Kraig

John,

Perhaps that is part of my problem. I lack an understanding of how to
calculate pi using numbers of terms that are powers of 2 in C++, in the
most effective manner.

I do know I need a loop. However, I left it out because I feel it's
better to calculate pi properly, then move on to looping/incrementing
the terms. I hope that makes sense, John. Thank you for your help - it
is invaluable!

kraig
 
J

John Harrison

I do know I need a loop. However, I left it out because I feel it's
better to calculate pi properly, then move on to looping/incrementing the
terms.

That's a good approach, break down the problem into smaller parts and
concentrate on one part. I would have chosen to write the loop first and
then concentrate on the terms. But that's just personal preference.

john
 
O

osmium

Kraig said:
Perhaps that is part of my problem. I lack an understanding of how to
calculate pi using numbers of terms that are powers of 2 in C++, in the
most effective manner.

I do know I need a loop. However, I left it out because I feel it's
better to calculate pi properly, then move on to looping/incrementing
the terms. I hope that makes sense, John. Thank you for your help - it
is invaluable!

I am not at all sure that there is a series such as the one you conjecture
about. Is it possible you misunderstood the assignment? An assignment such
as "Computer the first n terms of the alternating series for pi" makes
perfect sense for an introductory programming course. The first hit on
google for <series pi> yields the necessary equation. The terms involve an
alternating sign so the instructor probably wants you to be clever in
computing the appropriate sign.

It's a poor way to compute pi, which is fine for an introductory course, you
can put in debugging statements and observe the result improving.
 
K

Kraig

John,

I'll transcribe quickly what it says. It is IMO hard to understand
precisely what it means, but here goes:

"Write a program which uses a function to calculate the value of pi from
the infinite series:

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

Print a table that shows the value of pi approximated for numbers of
terms that are powers of two, i.e., 1, 2, 4, 8, 16, etc. Print out that
number of terms. Give the function as input the number of terms to use.
The function then returns the calculated value of pi.

A sample output is:

#Terms Num Sum
1 4.000000000000
2 2.666666746139

(list continues to #Terms 16777216)"

I think perhaps I don't understand the problem. I can code it if I
understand it, but it's worded in such a way as to confuse me.

kraig
 
K

Kraig

Okay, I've gotten it this far:

#include <iostream.h>
#include <math.h>

#define NUM_OF_ELEMENTS 20000

int main()


{
double pi = 0;

// Calculating pi/4

for (long int n = 1; n <= NUM_OF_ELEMENTS; n++)


{
pi += (double) pow(-1, n+1)/(2*n-1);
}

// Calculating pi

pi *= 4;
cout << "pi value using " << NUM_OF_ELEMENTS << " elements is" " "
<< pi << " " " \n";
return 0;
}

Now I'm to the point I need to compute it for every number of terms that
is a power of two, all the way out to 16777216, and displaying it for
each term. I've gotten the first part working, finally.
 
J

John Harrison

Kraig said:
Okay, I've gotten it this far:

#include <iostream.h>
#include <math.h>

#define NUM_OF_ELEMENTS 20000

int main()


{
double pi = 0;

// Calculating pi/4

for (long int n = 1; n <= NUM_OF_ELEMENTS; n++)


{
pi += (double) pow(-1, n+1)/(2*n-1);
}

// Calculating pi

pi *= 4;
cout << "pi value using " << NUM_OF_ELEMENTS << " elements is" " " <<
pi << " " " \n";
return 0;
}

Now I'm to the point I need to compute it for every number of terms that
is a power of two, all the way out to 16777216, and displaying it for each
term. I've gotten the first part working, finally.
Kraig wrote:

I think you might be confusing yourself. You need to compute it exactly as
you are doing now, the requirement is that you print it only for numbers
that are a power of two. Something like this

for (long int n = 1; n <= NUM_OF_ELEMENTS; n++)
{
pi += (double) pow(-1, n+1)/(2*n-1);
if (n is a power of two)
cout << n << ' ' << pi << '\n';
}

You just have to work out a way to get the 'n is a power of two' part.
Something like this should work

int next_power_of_two = 1;
for (long int n = 1; n <= NUM_OF_ELEMENTS; n++)
{
pi += (double) pow(-1, n+1)/(2*n-1);
if (n == next_power_of_two)
{
cout << n << ' ' << pi << '\n';
calculate the next power of two
}
}

I'll leave you to work out the 'calculate the next power of two' part.

Another improvement you could make is to get rid of the pow(-1, n+1) part,
its very inefficient. All you need is a variable that is alternately +1
and -1 each time round the loop. You should be able to work out that without
using something as inefficient (and potentially inaccurate) as pow.

john
 
O

osmium

Kraig said:
I'll transcribe quickly what it says. It is IMO hard to understand
precisely what it means, but here goes:

"Write a program which uses a function to calculate the value of pi from
the infinite series:

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

Print a table that shows the value of pi approximated for numbers of
terms that are powers of two, i.e., 1, 2, 4, 8, 16, etc. Print out that
number of terms. Give the function as input the number of terms to use.
The function then returns the calculated value of pi.

I agree it is rather an odd problem; In C++ish pseudocode, I think he wants
something like this.

--start--
// get number of terms, n, from user

for(long i = 1; i<=n; i*2)
x = pi(long j) // compute j terms.of pi
x is there to de-obfuscate the thing
print x // for debuging
print n, last (most accurate) value obtained
--end--
now write the function that fits for: double pi(long) using the alternating
series mentioned elsewhere in the thread

Note that there is no #define
 
T

Thomas Matthews

Kraig said:
John,

Perhaps that is part of my problem. I lack an understanding of how to
calculate pi using numbers of terms that are powers of 2 in C++, in the
most effective manner.

I do know I need a loop. However, I left it out because I feel it's
better to calculate pi properly, then move on to looping/incrementing
the terms. I hope that makes sense, John. Thank you for your help - it
is invaluable!

kraig

I do this with a calculator when I'm bored in school. :)

Here is a main() function for calculating the first terms.
I'm using double instead of float because many of the library
functions use double. See the C++ FAQ below.

int main(void)
{
double result = 0;
const double numerator = 4.0;
double denomenator = 1.0;
const unsigned int num_terms = 4;

/* Note that the first term has an implied denomenator
* of 1 (one).
*/

// result = 0.0 + (4.0 / 1.0)
result = result + numerator / denomenator;
cout << "Denomenator: " << denomenator;
cout << ", Result: " << result << endl;


/* In generating the next term, the denomenator is
* incremented by 2.
* The sign of the term changes to negative, IOW
* the next term will be subtracted.
*/

// result = result - (4.0 / 3.0)
denomenator += 2;
result = result - numerator / denomenator;
cout << "Denomenator: " << denomenator;
cout << ", Result: " << result << endl;


/* As the pattern goes, increment the denomenator by
* two, then add in the next term:
*/
denomenator += 2;
result = result + numerator / denomenator;
cout << "Denomenator: " << denomenator;
cout << ", Result: " << result << endl;

denomenator += 2;
result = result - numerator / denomenator;
cout << "Denomenator: " << denomenator;
cout << ", Result: " << result << endl;

return 0;
}

There is a pattern to the above code. Which results in:
int main(void)
{
double result = 0;
const double numerator = 4.0;
double denomenator = 1.0;
const unsigned int num_terms = 4;

for (unsigned int i = 0;
i < num_terms / 2; // Two terms per loop.
i += 2)
{
result += numerator / denomenator;
cout << "Denomenator: " << denomenator;
cout << ", Result: " << result << endl;
denomenator += 2;

result -= numerator / denomenator;
cout << "Denomenator: " << denomenator;
cout << ", Result: " << result << endl;
denomenator += 2;
}

return 0;
}

Your challenge, should you accept it, is to alter the
loop so that it can handle any number of terms, not
just multiples of two. For example, set the
constant "num_terms" to 7.

After you have that working, add in the I/O to
prompt the user for the number of terms. Remember
to validate the user's input (for example, -2
for the quantity doesn't work).

The final revision is to make the program print the
output per the requirements.

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.comeaucomputing.com/learn/faq/
Other sites:
http://www.josuttis.com -- C++ STL Library book
 
K

Kraig

After much wringing of hands and pulling of hair, I have arrived at:

#include <iostream>
#include (cmath>
using namespace std;

int main()
{
double pi = 0;
double n = 0;
double x = 0;
double y = 0;

for(n = 1; n <=16777216; n*=2)
{
for(x = 1; x <= (2*n - 1); y++)
{
pi = pow(1, ((y +1)) * (4/x);
pi += pi;
x+=2;
}
cout << "pi value using " << n << " terms is " << pi << " " "
\n";
}
return 0;
}

This seems to basically work, but the values in output are not correct.
There is an error in the computation, but it is feeding from the first
if to the second if correctly, as evidenced in output. It outputs the
terms in powers of two, all the way to 16777216, as I wanted. Does
anyone see the error in the actual computation that I am missing?
Compile it, see the output, and you'll see what I'm talking about.
Thanks for any help you can provide.

kraig
 
K

Kai-Uwe Bux

Kraig said:
After much wringing of hands and pulling of hair, I have arrived at:

#include <iostream>
#include (cmath>
using namespace std;

int main()
{
double pi = 0;
double n = 0;
double x = 0;
double y = 0;

for(n = 1; n <=16777216; n*=2)
{
for(x = 1; x <= (2*n - 1); y++)
{
pi = pow(1, ((y +1)) * (4/x);

This sets pi to 1 since pow(1,whatever) is 1.
pi += pi;

Now, pi is 2.

And it exits the loop as two.
}
cout << "pi value using " << n << " terms is " << pi << " " "
\n";
}
return 0;
}

This seems to basically work, but the values in output are not correct.

Obviously you are trying to add the terms of some series for pi. Which one
do you have in mind.


Best

Kai-Uwe Bux
 
K

Kraig

I am attempting to pass powers of two, from one to 16777216, to a
calculation that approximates pi for each respective power of two
previously mentioned. It's the second loop, the calculation of pi using
the int created in the first loop, that is proving problematic.

kraig
 
K

Kai-Uwe Bux

Please do not top-post.

I am attempting to pass powers of two, from one to 16777216, to a
calculation that approximates pi for each respective power of two
previously mentioned.

Ok, I take the following from another post in this thread to be the
assignment:
"Write a program which uses a function to calculate the value of pi from
the infinite series:

pi = 4-(4/3)+(4/5)-(4/7)+(4/9)-(4/11)+...
[snip]

Let us focus on this part first. If I told you, to use this formula to
compute pi by adding the first 1000 terms of that series, what would your
loop look like?

Here is your inner loop (which would be the one that has to do it):Clearly, x is supposed to be the denominator. Also, I take the y++ at the
end to be a typo. You meant x++. But that woule get you even denominators,
too. Thus, you really want x+=2.Now, it is not wise to initialize pi within the loop. After all this means
that you forget everything you computed during the previous run.
Let us rectify this a little. A first draft should look like this:

unsigned long n = 2000;
double pi = 0.0;
for ( unsigned long x = 1; x <= (2*n-1); x+=2 ) {
pi += 4.0/x;
}

Now this is still off, because the series is alternating. So every other
run, we want to subtract.

Another problem is the order in which we add the terms: We start with big
terms and get smaller. From a numerical point of view, this is bad since
towards the end, we add numbers of different magnitudes.

With these hints you should be able to make the inner loop work.


Best

Kai-Uwe Bux
 
J

John Harrison

Kraig said:
I am attempting to pass powers of two, from one to 16777216, to a
calculation that approximates pi for each respective power of two
previously mentioned. It's the second loop, the calculation of pi using
the int created in the first loop, that is proving problematic.

You don't need a second loop, its easier than that, see my last two posts.

john
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,565
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top