My friend and I are way ahead in our computer programming class so we thought it would be fun to calculate pi. Little did we know we would spend the whole period debugging the damn thing without ever getting it to work. Here's the code:
#include <iostream>
usingnamespace std;
int main()
{
longdouble pi = 4;
// Initiates pi and assigns it the first value in the series: pi = 4 - (4 / 3) + (4 / 5) - (4 / 7) + (4 / 9)....
longdouble prev;
// Initiates prev, a variable used to test if the value of pi has reached its limit or not.
int d = 3;
// Initiates the denominator variable and assigns it the value of the first denominator.
int count = 0;
// Initiates the count variable, used to decide between the - or + operators used in the series.
while(true)
// Loops the series until it breaks.
{
if(count % 2 == 0)
// Executes the function if count is an even value.
{
prev = pi;
// Sets prev to equal pi. (Prev is the PREVious value of pi.)
pi = pi - (4 / d);
// Subtracts four over the current denominator from the current value of pi and assigns it as the new value of pi.
++count;
++d;
++d;
// Adds one to count (making it odd) and two to the denominator (making it the next odd number).
}
else
// Executes the function if count is an odd value.
{
prev = pi;
pi = pi + (4 / d);
// Adds four over the current denominator to the current value of pi and assigns it as the new value of pi.
++count;
++d;
++d;
}
if(prev == pi)
// Executes the function if the previous value of pi is equal to the current value of pi, which indicates that the value of pi has reached its limit.
{
break;
// Breaks the loop.
}
}
cout << "Pi equals " << pi << ".\n";
// Outputs the final value of pi.
return 0;
}
It's obviously dropping the decimal, but I have no idea why. Please help me figure out what the hell is wrong with this program!
A few interesting things to note:
-At first I had accidentally made the first two functions both subtract 4 divided by the denominator instead of making the second one add it, but pi still equaled three!
-I thought defining d as an integer might have caused the program to drop the decimal, but when I define d as anything else absolutely nothing happens. The console just sits there doing nothing.
4/d is integer division. Since d starts at 3 and is incremented by 2 every loop, pi is only ever subtracted 1, as 4/x=0 for all x>4.
4.0/d is floating point division. Alternatively, you can make d a double.
OK, I'm really grateful for your explanation of the problem as it relieves my curiosity of what the problem is, but as I said before, if I make d anything but an integer the program does absolutely nothing. I also tried replacing 4 / d with 4.0 / d but it had the same effect. What's causing my console to just sit there blankly if I try to implement floating point division??
EDIT: Sorry, you're right, my console isn't doing nothing, it's just thinking for a really, really, really long time. It eventually outputs pi if you stop the loop prematurely by replacing while(true) with something like while(count < 100). It's still not very accurate or useful, but at least I know the program works, it's just not very good at what it does. I guess this wasn't the most efficient way to calculate pi. Oh well.
Using == and != with floating point operands is in general a really bad idea. The two operators have exact semantics. Namely, the operands have to have the exact same binary value. The problem is that floating point operations are wildly inaccurate. It's usually much better to do something like close_enough(x,y)=abs(x-y)<epsilon, where epsilon is an appropriately small value.
Your condition is poorly thought-out, either way. long double has an absurdly large precision, so there are two possible scenarios:
1. Your program is basically counting upwards to 2^80, so it will eventually terminate. It will just take a really long time.
2. The program never terminates because you reach a point where prev and pi are going back and forth between the same two values because 4/d gives back long double's epsilon.
You also didn't consider the fact that d can overflow and loop around before the program terminates.