Click here to Skip to main content
15,886,519 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Well the title says it all really.

I am using this formula Bellard's formula
Wiki page is Bellard's formula

Now i understand (i think) the above formula, and i am trying to make a C# app that calculates PI to any digit the user asks for (i will put a limit once it works).

This is my rough C# code that i thought would work but its returning a only a few digits.

C#
double pi = 0;
for(int k = 0; k <= 25; k++)
{
    pi += ((Math.Pow((-1), k)) / (Math.Pow(2, (10 * k)))) * (-(Math.Pow(2, 5) / ((4 * k) + 1)) - (1 / ((4 * k) + 3)) + (Math.Pow(2, 8) / ((10 * k) + 1)) - (Math.Pow(2, 6) / ((10 * k) + 3)) - (Math.Pow(2, 2) / ((10 * k) + 5)) - (Math.Pow(2, 2) / ((10 * k) + 7)) + (1 / ((10 * k) + 9)));
}
pi = (1 / (Math.Pow(2, 6))) * pi;


And when i run that to say..k = 4 (so fourth digit) i get "3.14506349991935"
And if i change that k to something else like 100 i still only get those few digits right.

Can someone tell me what i'm doing wrong?

**EDIT**
I have also tried this

pi = 0;
for(int n = 0; n<=10 ; n++)
{	
      pi += (4/(8*n+1) - 1/(4*n+2) - 1/(8*n+5) - 1/(8*n+6)) / (Math.Pow(16, n));
}


But it just returns 4. I have a feeling i am either not understanding something or missing something small.
Posted
Updated 30-Apr-11 9:38am
v3
Comments
Alan N 30-Apr-11 17:20pm    
FYI, double has a precision of only 15-16 digits.
thexcodec 30-Apr-11 17:38pm    
what would you suggest i use?
Alan N 30-Apr-11 18:16pm    
Try searching for Arbitrary precision maths library. I've never used one so can't make a recommendation but this was one of the results http://www.fractal-landscapes.co.uk/bigint.html
Philippe Mori 30-Apr-11 19:45pm    
The second solution is effectively worst than the first because more computation are done in integer arithmetic. On first iteration, you would have:
pi = (4/1 - 1/2 - 1/5 - 1/6) / 1.0
pi = (4 - 0 - 0 - 0) / 1.0
pi = 4.0
Any subsequent iteration would add 0.0 to this result.
yesotaso 30-Apr-11 21:18pm    
If it was like:
pi += (4D/(8*n+1) - 1D/(4*n+2) - 1D/(8*n+5) - 1D/(8*n+6)) / (Math.Pow(16, n));
operator precedence and auto type cast would change scene but of course not even close to what he wants :)

Maybe I'm wrong but you always execute the for 26 times, if k is the number of digit and equal to number of times to execute the for, your for must be

for(int i = 0; i < k; i++)


if every for only add a new digit to pi this matter only affect to number of digits not to bad result.
 
Share this answer
 
v3
Comments
thexcodec 30-Apr-11 15:29pm    
you would have to define K other wise its a invalid loop.
Can you show me how you would do it?
thexcodec 30-Apr-11 15:32pm    
I also tried
int k = 4;
for(int i = 0; i < k; i++)
Still not working.
jesusangelkdt 30-Apr-11 15:38pm    
As I said this is supossing the number of k is equal to number of decimals and equal to the number of times to execute the for, but I tried this formula and seems to be bad, because no matter if k is 1, 20, 90 .... the results always is 201.xxxxxxxxxx.

Sorry but don't understand the formula itself.

Regards
thexcodec 30-Apr-11 15:39pm    
I messed up the formula and fixed my post but it still is not working correctly.
It will only return the first 3 digits right.
jesusangelkdt 30-Apr-11 16:25pm    
I've found this class to calculate pi with a certain number of digits, maybe this can save your time.

http://omegacoder.com/?p=91

Regards
Well, the first step to debug your solution was to print after each iteration, k, iteration result (delta) and cumulative sum (pi).

C#
double pi = 0;
for (int k = 0; k <= 25; k++)
{
    double delta = ((Math.Pow((-1), k)) / (Math.Pow(2, (10 * k)))) *
        (-(Math.Pow(2, 5) / ((4 * k) + 1)) 
         - (1 / ((4 * k) + 3)) 
         + (Math.Pow(2, 8) / ((10 * k) + 1)) 
         - (Math.Pow(2, 6) / ((10 * k) + 3)) 
         - (Math.Pow(2, 2) / ((10 * k) + 5)) 
         - (Math.Pow(2, 2) / ((10 * k) + 7)) 
         + (1 / ((10 * k) + 9)));

    delta /= (Math.Pow(2, 6));
    pi += delta;

    Console.WriteLine(string.Format("k={0}, delta={1}, pi={2}", k, delta, pi));
}


The result look like:

k=0, delta= 3,14523809523809,     pi=3,14523809523809
k=1, delta=-0,000174677880330454, pi=3,14506341735776
k=2, delta= 8,26144783365773E-08, pi=3,14506349997224
k=3, delta=-5,28924035141653E-11, pi=3,14506349991935
k=4, delta= 3,83576851413217E-14, pi=3,14506349991939
k=5, delta=-2,97726903990637E-17, pi=3,14506349991939
k=6, delta= 2,41181903757061E-20, pi=3,14506349991939
k=7, delta=-2,01195711199672E-23, pi=3,14506349991939
k=8, delta= 1,71468942661398E-26, pi=3,14506349991939


The first problem with your code is that you are incorectly doing some computation in integer arithmetic instead of double.

double d1 = 1 / 3;   // d1 = 0
double d2 = 1 / 3.0; // d2 = 0.333...
double d3 = 1.0 / 3; // d3 = 0.333...
double d4 = 1.0 / 3.0; // d4 = 0.333...


If you replace some integer constants with double, you will have more sensible result. Here is the modified code (I have changed only a few value to double for demonstration purpose.

C#
double pi = 0;
for (int k = 0; k &lt;= 25; k++)
{
    double delta = ((Math.Pow((-1), k)) / (Math.Pow(2, (10 * k)))) *
        (-(Math.Pow(2, 5) / ((4 * k) + 1.0))
         - (1.0 / ((4 * k) + 3))
         + (Math.Pow(2, 8) / ((10 * k) + 1.0))
         - (Math.Pow(2, 6) / ((10 * k) + 3.0))
         - (Math.Pow(2, 2) / ((10 * k) + 5.0))
         - (Math.Pow(2, 2) / ((10.0 * k) + 7))
         + (1 / ((10 * k) + 9.0)));
    delta /= (Math.Pow(2, 6));
    pi += delta;
    Console.WriteLine(string.Format("k={0}, delta={1}, pi={2}", k, delta, pi));
}



The result would look like:

k=0, delta= 3,14176587301587,     pi=3,14176587301587
k=1, delta=-0,000173301147482709, pi=3,14159257186839
k=2, delta= 8,17736604635702E-08, pi=3,14159265364205
k=3, delta=-5,22954018637708E-11, pi=3,14159265358975
k=4, delta= 3,78997628626364E-14, pi=3,14159265358979
k=5, delta=-2,94045250629684E-17, pi=3,14159265358979
k=6, delta= 2,38126583625258E-20, pi=3,14159265358979
k=7, delta=-1,98601694415512E-23, pi=3,14159265358979
k=8, delta= 1,69228385223704E-26, pi=3,14159265358979
k=9, delta=-1,46572566668089E-29, pi=3,14159265358979


Finally, as you can notice from this sample, after a few iterations, the displayed result won't change anymore. As it was mentionned in some comments above, you would have to somehow use large numbers to do the computation.

I have not read carefully the whole explanation in the provided links. But for task like this one, you must uses appropriate data type and also have some basic understanding on how floating point works and such.
 
Share this answer
 
v3
Comments
thexcodec 1-May-11 1:52am    
thanks a million!
thexcodec 1-May-11 2:54am    
After some research my above algorithm will not work. I will need to calculate pi digit by digit and store each value.

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