Click here to Skip to main content
14,027,355 members
Rate this:
 
Please Sign up or sign in to 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.

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 :)
Wonde Tadesse 30-Apr-11 19:48pm
   
@thexcodec May I ask why you want to calculate PI. Dot NET framework has a constant for PI in "System.Math.PI".
thexcodec 1-May-11 3:19am
   
to say i can. I want to know how its done. I don't like things given to me.
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 1

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.
   
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
thexcodec 30-Apr-11 16:37pm
   
it does save me time, but i really wanted to do this on my own just to see if i could do it.
Guess i failed...lol
Thanks anyway
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 2

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

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.

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.
   
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)

  Print Answers RSS
Top Experts
Last 24hrsThis month


Advertise | Privacy | Cookies | Terms of Service
Web06 | 2.8.190419.4 | Last Updated 1 May 2011
Copyright © CodeProject, 1999-2019
All Rights Reserved.
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100