home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 247_01 / bnarth1.c < prev    next >
Text File  |  1989-04-19  |  3KB  |  128 lines

  1. /*
  2.  *   MIRACL arithmetic routines 1 - multiplying and dividing BIG NUMBERS by  
  3.  *   integer numbers.
  4.  *   bnarth1.c
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include "miracl.h"
  9. #define abs(x)  ((x)<0? (-(x)) : (x))
  10. #define sign(x) ((x)<0? (-1) : 1)
  11.  
  12. /* access global variables */
  13.  
  14. extern small base;   /* number base     */
  15. extern int nib;      /* length of bigs  */
  16. extern int depth;    /* error tracing ..*/
  17. extern int trace[];  /* .. mechanism    */
  18. extern bool check;   /* overflow check  */
  19.  
  20. void premult(x,n,z)
  21. big x;
  22. big z;
  23. small n;
  24. { /* premultiply a big number by an int z=x.n */
  25.     int s,xl,m;
  26.     small carry;
  27.     if (ERNUM) return;
  28.     depth++;
  29.     trace[depth]=9;
  30.     if (TRACER) track();
  31.     if (notint(x))
  32.     {
  33.         berror(12);
  34.         depth--;
  35.         return;
  36.     }
  37.     if (n==0)  /* test for some special cases  */
  38.     {
  39.         zero(z);
  40.         depth--;
  41.         return;
  42.     }
  43.     if (x[0]>=0)
  44.     {
  45.         s=PLUS;
  46.         xl=x[0];
  47.     }
  48.     else
  49.     {
  50.         s=MINUS;
  51.         xl=(-x[0]);
  52.     }
  53.     if (n<0)
  54.     {
  55.         n=(-n);
  56.         s=(-s);
  57.     }
  58.     if (n==1)
  59.     {
  60.         copy(x,z);
  61.         insign(s,z);
  62.         depth--;
  63.         return;
  64.     }
  65.     if (x!=z) zero(z);
  66.     m=0;
  67.     carry=0;
  68.     while (m<xl || carry>0)
  69.     { /* multiply each digit of x by n */
  70.         m++;
  71.         if (m>nib && check)
  72.         {
  73.             berror(3);
  74.             depth--;
  75.             return;
  76.         }
  77.         carry=muldiv(x[m],n,carry,base,&z[m]);
  78.         z[0]=m;
  79.     }
  80.     if (s<0) z[0]=(-z[0]);
  81.     depth--;  
  82. }
  83.          
  84. small subdiv(x,n,z)
  85. big x;
  86. big z;
  87. small n;
  88. {  /*  subdivide a big number by an int   z=x/n  *
  89.     *  returns int remainder                     */ 
  90.     int i,s,sx,xl;
  91.     small r;
  92.     if (ERNUM) return 0;
  93.     depth++;
  94.     trace[depth]=10;
  95.     if (TRACER) track();
  96.     if (notint(x)) berror(12);
  97.     r=0;
  98.     if (n==0) berror(2);
  99.     if (ERNUM) 
  100.     {
  101.         depth--;
  102.         return 0;
  103.     }
  104.     sx=sign(x[0]);
  105.     s=sx*sign(n);  /* set sign of result */
  106.     if (n<0) n=(-n);
  107.     if (n==1) /* special case */
  108.     {
  109.         copy(x,z);
  110.         insign(s,z);
  111.         depth--;
  112.         return r;
  113.     }
  114.     xl=abs(x[0]);
  115.     if (x!=z) zero(z);
  116.     for (i=xl;i>0;i--)
  117.     { /* divide each digit of x by n */
  118.         z[i]=muldiv(r,base,x[i],n,&r);
  119.     }
  120.     z[0]=xl;
  121.     lzero(z);
  122.     if (s<0) z[0]=(-z[0]);
  123.     depth--;
  124.     if (sx<0) return (-r);
  125.     else      return r;
  126. }
  127.  
  128.