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

  1. /* +++Date last modified: 05-Jul-1997 */
  2.  
  3. /*
  4. **  bigfac.c -- put into the public domain by Carl Declerck
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10.  
  11. #define BUFFLEN 8192
  12. #define BUFFER ((char *) malloc(BUFFLEN))
  13.  
  14. int  main (void);
  15. void multiply (char *, char *, char *);
  16. void zero_buffer (char *);
  17. void minus_one (char *);
  18. int  isnull (char *);
  19. void factorial (char *);
  20.  
  21. main (void)
  22. {
  23.       char *g = BUFFER;
  24.  
  25.       printf ("Enter a number: ");
  26.       scanf ("%s", g);
  27.       printf ("Factorial of %s is: ", g);
  28.       factorial (g);
  29.       printf ("%s\n", g);
  30.       free (g);
  31.       return 0;
  32. }
  33.  
  34. void multiply (char *g1, char *g2, char *g3)
  35. {
  36.       int gp1, gp2, cumpos, respos, mod, div;
  37.       int cmod, cdiv, resoff, wdig1, wdig2, base;
  38.  
  39.       zero_buffer (g3);
  40.       for (gp2 = strlen(g2) - 1; gp2 >= 0; gp2--)
  41.       {
  42.             wdig2 = *(g2 + gp2) - 48;
  43.             resoff = strlen(g2) - gp2 - 1;
  44.             respos = BUFFLEN - resoff - 2;
  45.             for (gp1 = strlen(g1) - 1; gp1 >= 0; gp1--)
  46.             {
  47.                   wdig1 = *(g1 + gp1) - 48;
  48.                   mod = (wdig1 * wdig2) % 10;
  49.                   div = (wdig1 * wdig2) / 10;
  50.                   base = *(g3 + respos) - 48;
  51.                   cmod = (base + mod) % 10;
  52.                   cdiv = (base + mod) / 10 + div;
  53.                   *(g3 + respos) = (char)(cmod + 48);
  54.                   cumpos = --respos;
  55.                   while (cdiv > 0)
  56.                   {
  57.                         base = *(g3 + cumpos) - 48;
  58.                         *(g3 + cumpos--) = (char)((base + cdiv) % 10 + 48);
  59.                         cdiv = (base + cdiv) / 10;
  60.                   }
  61.             }
  62.       }
  63.       for (respos = 0; *(g3 + respos) == '0'; respos++)
  64.             ;
  65.       strcpy (g3, (char *) (g3 + respos));
  66.       if (*g3 == 0)
  67.             strcpy (g3, "0");
  68. }
  69.  
  70. void zero_buffer (char *buff)
  71. {
  72.       int cnt;
  73.  
  74.       for (cnt= 0; cnt < BUFFLEN; cnt++)
  75.             *(buff + cnt) = '0';
  76.       *(buff + BUFFLEN - 1) = 0;
  77. }
  78.  
  79. void minus_one (char *g)
  80. {
  81.       int p;
  82.       char digit;
  83.  
  84.       p = strlen(g) - 1;
  85.       digit = *(g + p);
  86.       while (digit == '0')
  87.       {
  88.             *(g + p--) = '9';
  89.             digit = *(g + p);
  90.       }
  91.       *(g + p) -= 1;
  92. }
  93.  
  94. int isnull (char *g)
  95. {
  96.       int p, ok = 1;
  97.  
  98.       for (p = 0; p < (int)(strlen(g)); p++)
  99.             if (*(g + p) != '0')
  100.                   ok = 0;
  101.       return (ok);
  102. }
  103.  
  104. void factorial (char *g)
  105. {
  106.       char *h1 = BUFFER, *h2 = BUFFER;
  107.  
  108.       strcpy (h1, "1");
  109.       while (!isnull(g))
  110.       {
  111.             multiply (h1, g, h2);
  112.             strcpy (h1, h2);
  113.             minus_one (g);
  114.       }
  115.       strcpy (g, h1);
  116.       free (h1);
  117.       free (h2);
  118. }
  119.  
  120. /*
  121. **  The principal function is multiply(), it 'multiplies' two
  122. **  character-strings of arbitrary length and puts the result
  123. **  into a third.  8192 bytes is enough for 1000!, beyond that
  124. **  the buffer-size may need to be incremented.
  125. */
  126.