Thread: maximizing digits

  1. #1
    Registered User
    Join Date
    Dec 2008
    Posts
    2

    maximizing digits

    i created the following program to calculate the digits of pi; however, it begins to approach pi, then starts to fall apart and eventually just returns values of 0. i believe that his is because it is rounding all the variable to too few digits. how can i maximize the number of digits it uses? right now i have it set at 18 after the decimal place, because that is all it was doing anyway.

    Code:
    #include <stdio.h>
    #include <math.h>
    #include <stdlib.h>
    
    int main()
    {
        long double r,n,a,s,p;
    	r=0;
    	a=.5;
    	while (r==r)
    		{
    			n=3*pow(2,(r));
    			s=2*sqrt(1-(a*a));
    			p=(s*n)/2;
    			printf("pi=%1.18Lf",p);
    			getchar();
    			system ("cls");
    			a=sqrt((1+a)/2);
    			r++;
    		}
    	return (0);
    }

  2. #2
    Registered User carrotcake1029's Avatar
    Join Date
    Apr 2008
    Posts
    404
    Well, your variables are obviously going to overflow eventually, giving you undefined results. Calculate how many iterations it takes to accurately calculate pi and end the loop there.

  3. #3
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    agree with carrotcake1029; s approaches zero while n grows exponentially and eventually the result of s*n becomes zero.
    best to break from the loop as soon as the value of pi comes close to however many digits of precision you have in mind.

  4. #4
    Registered User
    Join Date
    Dec 2008
    Posts
    2
    The results deteriorate long before the variables overflow. whats happening is the the value of s gets so small (when r only equals about 25) that the program is rounding it to 0. which makes pi=0. how can i stop it from rounding? and what language to people use to calculate billions of digits of pi, just out of curiosity?

    Edit: it only gets to about 8 digits. then they start to change to incorrect digits. then it turns to 0

  5. #5
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    To "calculate billions of digits of pi", you need to use some bignum library like GMP. They implement numbers with virtually infinite precision at the expense of speed and memory usage (compared to native types).

  6. #6
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Quote Originally Posted by cyberfish View Post
    To "calculate billions of digits of pi", you need to use some bignum library like GMP. They implement numbers with virtually infinite precision at the expense of speed and memory usage (compared to native types).
    And unless you're doing exactly what cyberfish explains, it's really best just to hardcode PI as a constant. Because that's kinda what it is. A constant .

  7. #7
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    This is a program <author unknown>, that easily calculates a thousand or more digits of pi, using just standard libraries - in Turbo C!

    I have not checked the accuracy of the calculations beyond the handful that I recall.

    It is designed to run from the command line using:

    longpi n

    to have it calculate the first n digits of pi. I have modified it to run from the IDE, and to calculate 1,000 digits. Easily changed back, of course.

    Code:
    //longpi.c Author unknown - runs WAY fast!
    #include <stdio.h>
    
    long kf,ks,*mf,*ms;
    long cnt,n,temp,nd;
    long i;
    long col,col1;
    long loc,stor[21];
    FILE *fp;
    
    //function shift
    shift(l1,l2,lp,lmod)
      long *l1,*l2,lp,lmod;
    {
      long k;
      k=((*l2)>0 ? (*l2)/lmod : -(-(*l2)/lmod)-1);
      *l2 -= k*lmod;
      *l1 += k*lp;
    }
    //function yprint
    yprint(m)
      long m;
    {
      if (cnt < n)
        {
          if (++col==11)
    	{
    	   col = 1;
    	   if (++col1==6)
    	   {
    	      col1=0;
    	      fprintf(fp,"\n");
    	      printf("\n");
    	      fprintf(fp,"%4ld",m%10);
    	      printf("%4ld",m%10);
    	    }
    	    else {
    	      fprintf(fp,"%3ld",m%10);
    	      printf("%3ld",m%10);
    	    }//end else
    	}
            else {
                fprintf(fp,"%ld",m);
                printf("%ld",m);
    	}//end if(++col == 11)
    	cnt++;
        }
    }
    //function xprint
    xprint(m)
      long m;
    {
      long ii,wk,wk1;
      if (m<8)
        {
          for (ii=1; ii<=loc;)
    	yprint(stor[ii++]);
          loc=0;
        }
      else
        if (m>9)
        {
          wk = m/10;
          m %= 10;
          for (wk1=loc; wk1>=1;wk1--)
          {
    	 wk += stor[wk1];
    	 stor[wk1] = wk % 10;
    	 wk /= 10;
          }
        }//end of else
        stor[++loc] = m;
    }
    
    int main(argc,argv)
      int argc;
      char *argv[];
    {
      int i=0;
      stor[i++] = 0;
      argc = 5;
      if (argc < 2)
      {           
        fprintf(stderr,"Format is:\n\tlongpi <# of places>\n");
        exit();
      }
      //n = atoi(argv[1]); this is part of the code for running it from the command line.
      n = 1000;  //default is 1000 digits.
      mf = (long *)calloc((int)n+3, sizeof(long));
      if (mf==0)
      {
        fprintf(stderr,"Memory allocation failure [mf]\n");
        exit();
      }
      ms = (long *)calloc((int)n+3, sizeof(long));
      if (ms==0)
      {
        fprintf(stderr,"Memory allocation failure [ms]\n");
        exit();
      }
    
        printf("Memory allocated.\n");
        fp = fopen("df1:pi.out","w");
        fprintf(fp,"\nThe following is an approximation of PI to %ld digits\n",(long)n);
        printf("\nThe following is an approximation of PI to %ld digits\n",(long)n);
       
        cnt = 0;
        kf = 25;
        ks = 57121L;
        mf[1] = 1;
        for (i=2; i<=n; i+=2)
        {
            mf[i] = -16;
            mf[i+1] = 16;
        }
    
        for (i=1; i<=n; i+=2)
        {
            ms[i] = -4;
            ms[i+1] = 4;
        }
        fprintf(fp,"\n 3.");
        printf("\n 3.");
        while (cnt < n)
        {
            for (i=0; ++i<=n-cnt;)
            {
                mf[i] *= 10;
                ms[i] *= 10;
            }
            for (i=n-cnt+1; --i>=2;)
            {
                temp = 2*i-1;
                shift(&mf[i-1],&mf[i],temp-2,temp*kf);
                shift(&ms[i-1],&ms[i],temp-2,temp*ks);
            }
            nd = 0;
            shift(&nd,&mf[1],1L,5L);
            shift(&nd,&ms[1],1L,239L);
            xprint(nd);
        }
        printf("\n\nCalculations Completed! Press Enter When Ready \n");
        nd = getchar();
        return 0;
    }

  8. #8
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Ah yes, the old pi = 16 arctan(1/5) - 4 arctan(1/239) calculation.
    It would probably run a lot faster with a bignum library.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. decimal to number if digits in different bases
    By jorgejags in forum C Programming
    Replies: 21
    Last Post: 09-24-2008, 12:55 PM
  2. reverse a number digits
    By tootoo in forum C++ Programming
    Replies: 3
    Last Post: 04-06-2007, 11:24 AM
  3. Counting letters and digits
    By FeNCinGeR in forum C++ Programming
    Replies: 3
    Last Post: 04-06-2006, 11:39 AM
  4. Hex digits stored in char array.
    By Kevinmun in forum C Programming
    Replies: 8
    Last Post: 11-18-2005, 04:05 PM
  5. Odd/Even Digits in a Number-Help!
    By ProgrammingDlux in forum C++ Programming
    Replies: 2
    Last Post: 02-27-2002, 10:39 PM