home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 228_01 / pi.c < prev    next >
Text File  |  1987-07-31  |  5KB  |  216 lines

  1. /*
  2. HEADER:         CUGXXX;
  3. TITLE:          Pi calculator;
  4. DATE:           3-20-86;
  5. DESCRIPTION:    Computes pi to the specified number of decimal places;
  6. KEYWORDS:       Pi;
  7. FILENAME:       PI.C;
  8. WARNINGS:       Execution time is nearly proportional to the square of
  9.                 the number of digits computed, 10000 digits take >51 hours;
  10. AUTHORS:        R. E. Sawyer;
  11. COMPILER:       Desmet C V2.4 on PC-DOS V2.1;
  12. REFERENCES:     US-DISK 1308;
  13. ENDREF
  14. */
  15. /*   pi.c
  16. *    a program to compute pi to an arbitrary number of decimal places
  17. *
  18. *    Method:  Numbers are represented as character arrays, with each
  19. *          character being one decimal digit of the number.    All
  20. *          numbers so represented are assumed to be non-negative
  21. *          and less than ten, e.g.
  22. *          3.14159...  <-->  a[] = {3, 1, 4, 1, 5, 9, ...}
  23. *          1/8          <-->  a[] = {0, 1, 2, 5, 0, 0, ...}
  24. *          1/57          <-->  a[] = {0, 0, 1, 7, 5, 4, ...}
  25. *          The value of pi is computed using the identity
  26. *          pi = 24 arctan(1/8) + 8 arctan(1/57) + 4 arctan(1/239),
  27. *          where arctan(x) = x - x*x*x/3 + x*x*x*x*x/5 - ...
  28. *          and the arithmetic is performed on the numbers as arrays.
  29. *
  30. *    Accuracy:    All digits are correct -- verified to 10000 digits;
  31. *        the unsigned data type should handle over 50000 digits,
  32. *        but for more than that, longs should be used instead.
  33. *
  34. *    Timing:  Execution time is nearly proportional to the square of
  35. *          the number of digits computed; some approximate times on
  36. *          an IBM-PC:
  37. *             200 digits      1m 17s
  38. *             500          7m 45s
  39. *            1750          1h 34m
  40. *               10000         51h 08m
  41. *
  42. *    Language:    C (DeSmet 2.4, PC-DOS 2.1)
  43. *
  44. *    Author:  R. E. Sawyer, 3620 Spencer St. 30, Torrance, CA 90503
  45. *
  46. *    Date:  19 Jan 84
  47. */
  48.  
  49. #define MAXDIGITS    30000       /*maximum number of digits allowed*/
  50. #define EXTRA         3           /*extra digits computed internally*/
  51. #define MAXSIZ         MAXDIGITS + EXTRA
  52. #define TRUE 1
  53. #define FALSE 0
  54.  
  55. int numDigits;               /*number of digits requested*/
  56. int hiDigit;               /*highest array index needed*/
  57.  
  58. main(argc, argv)
  59.     int argc;
  60.     char *argv[];
  61.     {
  62.     char pi[MAXSIZ],
  63.      tmp[MAXSIZ];
  64.     prolog(argc, argv);
  65.     arctan(pi, 8);
  66.     mul(pi, 24);
  67.     arctan(tmp, 57);
  68.     mul(tmp, 8);
  69.     add(pi, tmp);
  70.     arctan(tmp, 239);
  71.     mul(tmp, 4);
  72.     add(pi, tmp);
  73.     report(pi);
  74.     }
  75. /*-------------validate user request */
  76. void prolog(ac, av)
  77.     int ac;
  78.     char *av[];
  79.     {
  80.     if ( ac != 2)
  81.     {
  82.     printf("\nUsage:  pi <numberOfDigits>\n");
  83.     exit();
  84.     }
  85.     if ((numDigits = atoi(av[1])) > MAXDIGITS)
  86.     {
  87.     printf("\n<numberOfDigits> must not exceed %d\n", MAXDIGITS);
  88.     exit();
  89.     }
  90.     hiDigit = numDigits + EXTRA - 1;
  91.     }
  92. /*-------------write (a[]) to stdout*/
  93. void report(a)
  94.     char a[];
  95.     {
  96.     int i;
  97.  
  98.     printf("\n%u.\n", a[0]);
  99.     for (i = 1; i < numDigits; ++i)
  100.     printf("%u", a[i]);
  101.     printf("\n");
  102.     }
  103. /*-------------replace (a[]) by arctan(1/n) */
  104. void arctan(a, n)
  105.     char a[];
  106.     unsigned n;
  107.     {
  108.     char t[MAXSIZ];
  109.     unsigned k, nn;
  110.     int isMinus;
  111.  
  112.     zero(t);
  113.     t[0] = 1;
  114.     div(t, n);
  115.     zero(a);
  116.     add(a, t);
  117.     nn = n * n;
  118.     k = 1;
  119.     isMinus = TRUE;
  120.     do
  121.     {
  122.     mul(t, k);
  123.     k += 2;
  124.     div(t, k);
  125.     div(t, nn);
  126.     if (isMinus)
  127.         sub(a, t);
  128.     else
  129.         add(a, t);
  130.     isMinus = !isMinus;
  131.     }
  132.     while (isNotZero(t));
  133.     }
  134. /*-------------set (a[]) equal to 0 */
  135. void zero(a)
  136.     char a[];
  137.     {
  138.     int i;
  139.  
  140.     for (i = 0; i <= hiDigit; ++i)
  141.     a[i] = 0;
  142.     }
  143. /*-------------replace (a[]) by (a[])*n */
  144. void mul(a, n)
  145.     char a[];
  146.     unsigned n;
  147.     {
  148.     int i;
  149.     long b;
  150.  
  151.     for (i = hiDigit, b = 0; i >= 0; --i)
  152.     {
  153.     b = (long)(a[i]) * n  +  b / 10L;
  154.     a[i] = b % 10L;
  155.     }
  156.     }
  157. /*-------------replace (a[]) by (a[])/n */
  158. void div(a, n)
  159.     char a[];
  160.     unsigned n;
  161.     {
  162.     int i;
  163.     long b;
  164.     for (i = 0, b = 0; i <= hiDigit; ++i)
  165.     {
  166.     b = 10L * (b % n) + (long)(a[i]);
  167.     a[i] = b / n;
  168.     }
  169.     }
  170. /*-------------replace (a[]) by (a[])+(b[]) */
  171. void add(a, b)
  172.     char a[], b[];
  173.     {
  174.     int i;
  175.  
  176.     for (i = hiDigit; i >= 0; --i)
  177.     {
  178.     if (a[i] + b[i] > 9)
  179.         {
  180.         a[i] -= 10 - b[i];
  181.         ++a[i-1];
  182.         }
  183.     else
  184.         a[i] += b[i];
  185.     }
  186.     }
  187. /*-------------replace (a[]) by (a[])-(b[]) */
  188. void sub(a, b)
  189.     char a[], b[];
  190.     {
  191.     int i;
  192.  
  193.     for (i = hiDigit; i >= 0; --i)
  194.     {
  195.     if (a[i] + 1 < b[i] + 1)
  196.         {
  197.         a[i] += 10 - b[i];
  198.         --a[i-1];
  199.         }
  200.     else
  201.         a[i] -= b[i];
  202.     }
  203.     }
  204. /*-------------test whether (a[]) is 0 */
  205. int isNotZero(a)
  206.     char a[];
  207.     {
  208.     int i;
  209.  
  210.     for (i = 0; i <= hiDigit; ++i)
  211.     if (a[i] != 0)
  212.         return TRUE;
  213.     return FALSE;
  214.     }
  215.  
  216.