Thread: Approximate the value of pi using circle mehod?

  1. #1
    Registered User
    Join Date
    Oct 2010
    Posts
    8

    Approximate the value of pi using circle mehod?

    Hello

    I'm trying to write a program which approximate the value of pi using the area of a quarter circle using rectangles. I wrote the program and it works fine, however the last 2 output( 100000 and 1000000 iterations) are not exactly the same as the one at the example.

    Here is the code: Consider RADIUS as "2"

    Code:
    double circle_pi(int rectangles)
    {
    double Width=RADIUS/(double)rectangles;
    double Height=0;
    double Area=0;
    double Pi=0;
    double x=0;
    
    x=Width/RADIUS;
    
    for( int i=0; i < rectangles; i++)
    {
    Height=sqrt((RADIUS*RADIUS)-(x*x));
    Area=Width*Height;
    Pi+=Area;
    x+=Width;
    }
    return Pi;
    
    }

    and the output is:

    Approximations for pi
    Iterations Circle Method
    --------------------------------------…
    1 3.464101615138
    10 3.152411433262
    100 3.141936857900
    1000 3.141603544913
    10000 3.141592998025
    100000 3.141592664486
    1000000 3.141592653923

    and the example output:
    Iterations Circle Method
    --------------------------------------…
    1 3.464101615138
    10 3.152411433262
    100 3.141936857900
    1000 3.141603544913
    10000 3.141592998025
    100000 3.141592664482
    1000000 3.141592653934

  2. #2
    Registered User
    Join Date
    Oct 2010
    Posts
    8
    I made a little bit of research and it seems like the way I'm doing it is prone to floating-point precision issues. Can anyone tell me how to solve this issue?

    I changes the code a little bit its more clear now

    Code:
    double circle_pi(int rectangles)
    {
    	double Width=RADIUS/(double)rectangles;
    	double Midpoint=Width/RADIUS;
    	double Pi=0;
    	for( int i=0; i < rectangles; i++)
    	{
    		double Height=sqrt((RADIUS*RADIUS)-(Midpoint*Midpoint));
    		double Area=Width*Height;
    		Pi+=Area;
    		Midpoint+=Width;
    	}
    	return Pi;
    }

  3. #3
    Registered User
    Join Date
    Oct 2010
    Posts
    107
    I don't know how to solve your issue using that method. My guess is that as you increase the number of rectangles, you add up numbers so small they can't be represented accurately so the error multiplies rapidly. I am really not an expert on floating-point arithmetic. But you can do any number of other things. One idea would be to find a series that is known to converge on pi and compute it out to a certain number of terms. Go to it. :P

    I tried Formula 49:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    // Computing PI by F. Bellard series
    // http://mathworld.wolfram.com/PiFormulas.html
    int main (void)
    {
    	long double pi = 0;
    	long double sum = 0;
    
    	int n;
    	for(n = 0; n <= 20; n++)
    	{
    		long double prod_a = pow(-1, n) / pow(2, 10*n);
    		long double prod_b =
    				-32.0/(4.0*(long double)n+1) 
    				-1.0/(4.0*(long double)n+3.0) 
    				+256.0/(10.0*(long double)n+1.0) 
    				-64.0/(10.0*(long double)n+3.0)
    				-4.0/(10.0*(long double)n+5.0) 
    				-4.0/(10.0*(long double)n+7.0)
    				+1.0/(10.0*n+9.0);
    		sum += prod_a * prod_b;
    
    		pi = sum / 64;
            printf("Iteration %d PI = %.40Lg\n", n, pi);
    	}
    
    	return 0;
    }
    Output:
    Code:
    Iteration 0 PI = 3.141765873015873015939788959194345352444
    Iteration 1 PI = 3.14159257186839030646409443026101371288
    Iteration 2 PI = 3.141592653642050769931259868172901406069
    Iteration 3 PI = 3.141592653589755367981445344227608984511
    Iteration 4 PI = 3.141592653589793267786267616514805922634
    Iteration 5 PI = 3.141592653589793238295968524909085317631
    That's 18 digits correct, and we can't do any better than that unless we do something smarter like use a type with higher precision. I assume types have been invented for this. I don't have them.
    Last edited by QuadraticFighte; 10-18-2010 at 04:58 AM.

  4. #4
    Registered User
    Join Date
    Oct 2010
    Posts
    8
    I don't get it. the formula I'm using in the code is correct. The problem is in floating point numbers. I understand the solution, but I don't know how to apply it to my code.

    This is the problem;

    If I have this:

    double x = 1.0 / 3.0;

    both of these statements are supposed to do the same thing:

    x + x + x + x + x + x;
    6 * x;

    However, since the value of x is probably not exact (rounding errors), each time I add it, I introduce a little more rounding error. If I multiply it, I still introduce the error, but only once. If you add enough x's together, you will see that the value diverges from the value you get by multiplying once.

    Also note that this has the same problem, although you may be fooled into thinking that you aren't adding x over and over again:

    total = 0;
    for (i = 0; i < 6; i++)
    total += x;

    Here's a sample program that demonstrates the differences:

    Code:
    int count;
        for (count = 10; count <= 100000000; count *= 10)
        {
          double x = 1.0 / count;
          double multiplied = x * count;
          double added = 0;
          int i;
    
          for (i = 0; i < count; i++)
            added += x;
    
          printf("iterations: %i, x = %.8f\n", count, x);
          printf("    multiplied = %.14f\n", multiplied);
          printf("         added = %.14f\n", added);
          printf("\n");
        }

    iterations: 10, x = 0.10000000
    multiplied = 1.00000000000000
    added = 1.00000000000000

    iterations: 100, x = 0.01000000
    multiplied = 1.00000000000000
    added = 1.00000000000000

    iterations: 1000, x = 0.00100000
    multiplied = 1.00000000000000
    added = 1.00000000000000

    iterations: 10000, x = 0.00010000
    multiplied = 1.00000000000000
    added = 0.99999999999991

    iterations: 100000, x = 0.00001000
    multiplied = 1.00000000000000
    added = 0.99999999999808

    iterations: 1000000, x = 0.00000100
    multiplied = 1.00000000000000
    added = 1.00000000000792

    iterations: 10000000, x = 0.00000010
    multiplied = 1.00000000000000
    added = 0.99999999975017

    iterations: 100000000, x = 0.00000001
    multiplied = 1.00000000000000
    added = 1.00000000228987

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Use a long double, instead of a double. After you've reached your largest data type you can use in your program, you're toast with that program design.

    This is a pi approximation from Dr. Math.

    Code:
    /* 
    pi.c - computes pi to 4,000 digits. From Dr. Math's website . Minor changes
    made to accomodate more digits (up from 800), etc.
    */
    
    #include <stdio.h>
    
    int i = 0;
    long int a = 10000,b,c=14000,d,e,f[14001],g; //was 2800 and 2801 for c and f
    
    int main() {
    
      /*   Use this code if you want it output to a file called PI.DAT. */
      /*FILE *fptr; 
      if ((fptr = fopen("PI.DAT", "w")) == NULL) 
      */
      
      printf("\n\n\n\n");
      for (;b-c;) f[b++]=a/5;
    
      /* original line - */
       for (;d=0,g=c*2;c-=14, printf("%.4d",e+d/a), e=d%a, i+=4) 
      
      /* for file output to PI.DAT */
       /* for (;d=0,g=c*2;c-=14, fprintf(fptr,"%.4d",e+d/a), printf("%.4d",e+d/a), e=d%a, i+=4) */
    
      /* 
        if you change "c-=14 to c-=(any number less than 14) you get a lot more digits.
        Eventually, they veer  away from the values for Pi, however. (at about 3400 digits.)
      */
          for(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b);
    
      printf("\nDigits found: %d",i);
    
    /*  fclose(fptr); */
      printf("\n\n\t\t\t    Program Complete - Press Enter When Ready\n");
      b = getchar();   
      return(0);
    }
    There are faster programs for this, and programs that will give you many more digits of Pi, but they're incomprehensible to me.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Circle Program Issues
    By hannah_banana10 in forum C++ Programming
    Replies: 9
    Last Post: 04-07-2010, 03:54 PM
  2. Pi - Hm, somethign is not right here.
    By MadnessRed in forum C++ Programming
    Replies: 8
    Last Post: 09-12-2008, 01:07 PM
  3. circle problem
    By gunghomiller in forum C++ Programming
    Replies: 10
    Last Post: 07-14-2007, 06:40 PM
  4. circle filling
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 06-08-2002, 05:37 AM
  5. point lies in circle?
    By cozman in forum Game Programming
    Replies: 3
    Last Post: 12-20-2001, 04:39 PM