home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / snip9707.zip / SPIGOT.C < prev    next >
C/C++ Source or Header  |  1997-07-05  |  3KB  |  110 lines

  1. /* +++Date last modified: 05-Jul-1997 */
  2.  
  3. /*
  4.  This program was based on a Pascal program posted in the FIDO 80XXX
  5.  assembly conference.  That Pascal program had the following comment:
  6.  
  7.                     ------------------------
  8.  This program, which produces the first 1000 digits of PI, using
  9.  only integer arithmetic, comes from an article in the "American
  10.  Mathematical Monthly", Volume 102, Number 3, March 1995, page
  11.  195, by Stanley Rabinowitz and Stan Wagon.
  12.                     ------------------------
  13.  
  14.  My C implementation is placed into the public domain, by its author
  15.  Carey Bloodworth, on August 22, 1996.
  16.  
  17.  I have not seen the original article, only that Pascal implementation,
  18.  but based on a discussion in the 80XXX conference, I believe the
  19.  program should be accurate to at least 32 million digits when using
  20.  long unsigned integers.  Using only 16 bit integers causes the
  21.  variables to overflow after a few hundred digits.
  22. */
  23.  
  24. #include <stdio.h>
  25.  
  26. long unsigned int i, j, k, nines, predigit;
  27. long unsigned int q, x, numdig, len;
  28. long unsigned int *pi;
  29.  
  30. int printed = 0, line = 1;
  31.  
  32. void OutDig(int dig)
  33. {
  34.       putchar(dig);
  35.       printed++;
  36.       if ((printed%50) == 0)
  37.       {
  38.             printed = 0;
  39.             printf("\nL%04d:   ", line++);
  40.       }
  41.       else if ((printed%10) == 0)putchar(' ');
  42. }
  43.  
  44. int main(int argc, char *argv[])
  45. {
  46.       if (argc < 2)
  47.       {
  48.             printf("I need to know how many digits to compute\n");
  49.             return 1;
  50.       }
  51.  
  52.       numdig = atol(argv[1]);
  53.       len = (numdig*10)/3;
  54.  
  55.       pi = (long unsigned int *)malloc((len+1)*sizeof(long unsigned int) );
  56.       if (pi == NULL)
  57.       {
  58.             printf("Unable to allocate memory\n");
  59.             return 1;
  60.       }
  61.  
  62.       for (x = len; x > 0; x--)
  63.             pi[x] = 2;
  64.  
  65.       printf("L0001: 3.");
  66.  
  67.       nines = 0;
  68.       predigit = 0;
  69.       for (j = 0; j <= numdig; j++)
  70.       {
  71.             q = 0;
  72.             for (i = len; i > 0; i--)
  73.             {
  74.                   x = 10 * pi[i]+ q * i;
  75.                   pi[i] = x % (2 * i - 1);
  76.                   q = x / (2 * i - 1);
  77.             }
  78.             pi[1] = q % 10; q = q / 10;
  79.             if (q == 9)
  80.                   nines++;
  81.             else if (q == 10)
  82.             {
  83.                   OutDig('1' + predigit);
  84.                   while (nines)
  85.                   {
  86.                         OutDig('0');
  87.                         nines--;
  88.                   }
  89.                   predigit = 0;
  90.                   fflush(stdout);
  91.             }
  92.             else
  93.             {
  94.                   if (j > 1)
  95.                         OutDig('0' + predigit);
  96.                   while (nines)
  97.                   {
  98.                         OutDig('9');
  99.                         nines--;
  100.                   }
  101.                   predigit = q;
  102.                   fflush(stdout);
  103.             }
  104.       }
  105.       OutDig(predigit + '0');
  106.  
  107.       free(pi);
  108.       return 0;
  109. }
  110.