Sindbad~EG File Manager

Current Path : /usr/home/beeson/MathXpert/bignums/
Upload File :
Current File : /usr/home/beeson/MathXpert/bignums/bignum.c

/* Bignum arithmetic package by M. Beeson */
/* Uses dynamic arrays instead of linked lists */
/* includes  addition, subtraction, multiplication, division, exponentiation,
        gcd, conversion to decimal form, and output.  */
/* Instructions for use are given in bignum.h */

/*
11.3.88 Original date
5.3.94 modified for Windows;
                 put a static copy of shortshiftgcd here
                 introduced variable 'aa'  to avoid a warning message
5.27.94 changed MAKELONG to MAKE_LONG
1.9.95  changed two remaining free 's to freespace in bigpower
3.13.96  Win32 port begun
3.21.96  eliminated macro MAKE_LONG in favor of calls to longmult and longdiv
3.24.95  addmod and mulmod written
3.25.96  rewrote bignum_double to use all significant digits
4.2.96   corrected syntax in 32-bit part of bignum_double
1.13.97  changed char* t= "four" to char t[5] in string_bignum and added t[4] = 0
3.31.97  changed assert(0) to return 1 in bignum_double.
6.18.97  Fixed a bug in bigdivide2 involving bigtrialq and trialq.  Last bug
                        fixed, nine years after original date?
9.18.97  defined MAXINT here as values.h is a Borland file not available in Microsoft
9.18.97  changed i,j to unsigned in bigsqrt, bigroot, and string_bignum to suppress a warning
1.29.97  BIGNUMS_DLL etc.
5.8.98   changed bits to unsigned from int in bigpower.  Added code to work around a
                        Microsoft bug in bigpower.  Introduced 'max' in biggcd.
5.9.98   used LEFTDIGIT one more place where explicit hex notation was before.
                        Rewrote subaux.
                        Corrected btod for 32-bit compilation
                        Corrected compare for 32-bit compilation
10.13.98 some changes to work around VC bug, namely a >> expression inside
                        an if behaves as if it were nonzero even though it should be zero.
                        Corrected subaux for the case old_borrow == 0.
11.6.98  Added #ifndef __BORLANDC__ around the definition of 'c' to avoid a
         warning that it's not used in 16-bit compilation.
1.15.99  corrected bigsqrt2 where we had the 16-bit and 32-bit code switched.
1.16.99  added freespace(bigtrialq.val) in a couple of places and made sure to set it
to NULL after it's been freed to avoid double freeing.  This should ensure that bigdivide
allocates ONLY the space needed for the answer.
1.16.99  added one more 'freespace(s.val)' in btod.
1.18.99  changed 32-bit space allocation in btod.
3.29.99  corrected initialization of teven in bigroot2
3.29.99  corrected change from 1.18.99; should be 2* instead of /2.
5.23.99  corrected bigroot2, removing a useless and incorrect error return
         that was causing failures, and removing looplimit, as it converges
         for ANY starting value.
6.20.99  modified bignum_string to handle separator > 2
10.24.01  j=1 changed to j=0 line 1063 in bigsqrt2
9.28.03  corrected mod_digit_aux
         Removed code used for 16-bit digits.
3.26.04  added line in bigdivide2 marked "Bug"  
4.6.04   changed "pshift" to "left_shift"  which is more descriptive       
4.15.04  Changed the spec of bigsqrt2 and bigsqrt, and added coded in bigsqrt2 at lines 1015-1016 
to meet the new spec.  Modified bigroot2 similarly.
4.15.04  Modifed bigdivide2 to trap the case when dividend == divisor. 
6.18.04  corrected that modification, which was blatantly wrong.  
9.2.04   modified bignum_string to get rid of ultoa, using sprintf instead.
4.23.13  corrected the order of conditions in the for-loop at line 409
4.26.13 put an assert and a cast into long_to_bignum
5.17.13 moved two lines down in string_bignum to avoid a memory leak.
        corrected bigminus2 at line 446
6.21.13 changed MAX to MAXDIGIT (to avoid a warning from Xcode)
6.28.13 modified long_to_bignum, because sizeof(unsigned) < sizeof(unsigned long) on the Mac.
11.24.23  initialized trialq to silence a warning
5.11.24  corrected long_to_bignum, the 2013 change was wrong.  
*/

#include <string.h>
#include <math.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>  /* strtoul */

#include "heap.h"  /* callocate and free2 */
#include "bignum.h"
#define MAXDIGIT ((digit) -1)

/* #define FFT   comment this to turn off FFT multiplication */

#define MAXINT 0x7fffffff

#define DIGITSIZE sizeof(digit)
static void left_shift(bignum x, int i, bignum *y);
static unsigned shortshiftgcd(unsigned u, unsigned v);

digit *getspace(unsigned n)
/* allocate space for n bignum digits */
/* call nospace() to handle errors */
{ digit *ans = (digit *) callocate(n,DIGITSIZE);
  if(ans == NULL)
     nospace();
  return ans;
}

/*________________ LOW-LEVEL ARITHMETIC ON DIGITS ____________*/

static void addaux(digit x, digit y, digit z, digit *sump, digit *carryp)
/* adds three digits producing a two-digit answer, carry and sum  */
/* assuming the carry digit is always either 0 or 1 as will be true when
   using this function for addition.
   Based on the idea that MAXDIGIT^m = 2^NN -1 -m, so that
   (n > (MAXDIGIT^m)) is the carry digit of n+m.   (Here MAXDIGIT^m is MAXDIGIT XOR m,
    and 2^NN is 2 to the power NN.)
   I am indebted to Bill Giles for pointing this trick out to me.
*/

{  digit temp = x+y;
   *sump = temp + z;
   if( x > (y^MAXDIGIT))
      { *carryp = 1;
        return;
      }
   else if ( temp > (z^MAXDIGIT) )
      { *carryp = 1;
        return;
      }
   *carryp = 0;
}
/*_________________________________________________________________________*/
static void subaux(digit x, digit y, digit old_borrow, digit *sump, digit *borrowp)
/* called only with x > 0  or old_borrow == 0 */
/*  subtract old_borrow + y from x if possible, getting *sump and
    setting *borrowp = 0.  If not possible, set *borrowp = 1 and
    subtract old_borrow + y from x + 2^NN */
/*  It is assumed that old_borrow is 0 or 1 */

{ digit s = y + old_borrow;
  if(s == 0)
     { if(old_borrow == 0)  /* so y == 0 too */
          *borrowp = 0;
       else
          *borrowp = 1;    /* when y == MAXDIGIT and old_borrow == 1 */
       *sump = x;
       return;
     }
  *sump = x-s;
  *borrowp = (s <= x) ? 0 : 1;
}
/*ADDITION________________________________________________________________*/
/* bigplus takes x and y and fills in the array ansp->val with the answer */

void bigplus2(bignum x, bignum y, bignum *ansp)
/* does not allocate space but presumes it done already */
{ unsigned i;
  digit carry = 0;
  if(x.ln < y.ln)
     { bigplus2(y,x,ansp);
       return;
     }

/* Now we can assume x is at least as long as y */

  ansp->ln = (unsigned)(x.ln + 1);

  for (i=0; i< y.ln; ++i)
     { addaux(x.val[i],y.val[i],carry,ansp->val + i,&carry);
         /*  ansp->val + i is the address of (*ansp).val[i] */
     }
  if( i < x.ln )  /* y has run out but x has not run out yet */
  for ( ; i < x.ln; ++i)
     addaux(x.val[i],0,carry, ansp->val + i, &carry);
  if (carry)
     ansp->val[i] = carry;
  else
     ansp->ln = (unsigned)(ansp->ln - 1);
     /* ansp->ln -= 1 generates a warning, and this line generates the same
        assembly code without generating a warning. */
}

void bigplus(bignum x, bignum y, bignum *ansp)
/* allocates space for the answer */
{  if(x.ln > y.ln)
      ansp -> val = getspace(x.ln+1);
   else
      ansp -> val = getspace(y.ln + 1);
   bigplus2(x,y,ansp);
}

/****************************************************************/
/* MULTIPLICATION */

void mult_by_digit2(bignum x, digit d, bignum *ansp)
/* does not allocate space */
/* multiply bignum by digit */
{  unsigned i;
   unsigned carry = 0;
   digit lo, hi;
   if(d==0)
      { ansp->ln = 1;
        ansp->val[0] = 0;
        return;
      }
   for(i=0; i< x.ln ; i++)
      { longmult(x.val[i],d,&lo,&hi);
        *(ansp->val+i) = lo + carry;
        carry = hi + (lo > (MAXDIGIT^carry));
      }
   if (carry )
      { ansp ->val [i] = carry;
        ansp->ln = (unsigned)(x.ln + 1);
      }
   else
      ansp->ln = x.ln;
}

void mult_by_digit(bignum x, digit d, bignum *ansp)
/* allocates space */
{ if(d==0)
     { ansp->val = getspace(2);
       ansp->ln = 1;
       ansp->val[0] = 0;
       return;
     }
  ansp->val = getspace(x.ln + 1);
  mult_by_digit2(x,d,ansp);
}

void bigmult2(bignum x, bignum y, bignum *ansp)
/* does not allocate space,expects it to have been done */
/* Inputs: x and y
   Output: ansp.  The array ansp->val will be filled during the computation.
   ansp->val is presumed to have length at least x.ln + y.ln even though the
   actual answer may be smaller.
*/
{
#ifdef FFT
fftmult(x,y,ansp);
#endif

#ifndef FFT
unsigned i,j;
digit lo,hi;
digit carry,tempcarry,tempsum;
if(x.ln < y.ln)
   { bigmult2(y,x,ansp);  /* always multiply longer by shorter */
     return;
   }
/* check x.ln + y.ln for possible overflow.  Although this is extremely
   unlikely, it only costs 2 comparisons most of the time to keep the
   program guaranteed correct. */
if(x.ln < MAXINT && y.ln < MAXINT)  /* as it almost always will be */
    ansp->ln =  x.ln + y.ln;  /* perhaps an overestimate */
else if (x.ln >= MAXINT && y.ln >= MAXINT)
    nospace();  /* overflow */
else if (x.ln + y.ln < MAXINT)
    nospace();  /* overflow; if one summand is more than MAX_INT and the other
                   is not, there is overflow iff the sum is < MAX_INT */
else
   ansp->ln = x.ln + y.ln;

/*initialize ansp->val to zero */
for(i=0;i<ansp->ln;i++)
   ansp->val[i] = 0;
/* start multiplying */
for(j=0; j< y.ln; j++)    /* multiply x by j-th digit of y and add to *ansp */
    { carry = 0;          /* re-initialize carry */
      for(i=0; i< x.ln; i++)
         { addaux(carry,(ansp->val)[i+j],0,&tempsum,&tempcarry);
           longmult(y.val[j],x.val[i],&lo,&hi);
           *(ansp->val+i+j) = lo + tempsum;
                /* ansp->val+i+j = &(ansp->val[i+j]) */
           carry = hi + (lo > (MAXDIGIT^tempsum));
           if (tempcarry)
              carry += tempcarry;
         }
         /* Now is there a leftover carry digit? */
      ansp->val[i+j] += carry;        /* zero or not */
    }
/* Now strip off leading zero if necessary */
if (ansp->val[ansp->ln-1] == 0)
   ansp->ln = (unsigned) (ansp->ln - 1);
  /* avoid the warning generated by ansp->ln -= 1 */
#endif
}

void bigmult(bignum x, bignum y, bignum *ansp)
/* allocates space for the answer */
{
  ansp->val = getspace(x.ln + y.ln);
  bigmult2(x,y,ansp);
}

/* TEST INEQUALITY _____________________________________________________*/

int compare(bignum x, bignum y)
/* return negative, 0, or positive value according as x<y, x=y, or x>y */
{ unsigned i;
  if ( x.ln > y.ln )
     return 1;
  else if (x.ln < y.ln)
     return -1;
  /*else x.ln = y.ln */
  for(i=x.ln -1;i != MAXDIGIT ;i--)
     { if(x.val[i] == y.val[i])
          continue;
       return (x.val[i] > y.val[i]) ? 1 : -1;
     }
  /* if you get this far they are equal */
  return 0;
}

/*________________modular arithmetic on unsigneds___________________*/
unsigned addmod(unsigned a, unsigned b, unsigned m)
/* return a+b mod m, even if a+b overflows an unsigned */

{ unsigned carry,sum;
  addaux(a,b,0,&carry,&sum);
  if(carry == 0)
     return sum % m;
  else if(m <= MAXINT)
     { a = a % m;
       b = b % m;
       return (a+b) % m;
     }
  if(a >= m)
     a = (unsigned) (a-m);  //  in effect, a = a % m, since a is no more than 2*m
  if(b >= m)
     b = (unsigned) (b-m);
  addaux(a,b,0,&carry,&sum);  //  (a+b) < 2m but it still could overflow
  if(carry)
     return (unsigned) (sum-m);  // correct in spite of overflow
  return sum;
}
/*___________________________________________________________________*/

unsigned mulmod(unsigned a, unsigned b, unsigned m)
/* return a*b mod m, even if a*b overflows an unsigned */
{ bignum p;  //  the product
  bignum q;  //  the quotient on division by m
  unsigned ans;
  digit data[2];
  digit data2[3];
  p.val = data;
  q.val = data2;
  longmult(a,b,data,data+1);
  divide_by_digit2(p,m,&q,&ans);
  return ans;
}
/*________________BIGNUM MOD DIGIT __________________________________*/

static digit mod_digit_aux(digit a, digit b, digit y)
/* return  (a << NN | b) % y, but do so even if
digits are the same size as unsigned longs. */

{  /*  (a*2^NN + b) mod y = (a%y * (2 * MAXINT) %y + b%y) %y  */
if(y < (1 << (NN/2 - 1 )))  /* usually this will be the case */
   /* Then we don't have to worry about overflow */
   return ((a%y)*2 *(MAXINT %y) + b%y) %y;
else
   { /* We do have to worry about overflow */
     unsigned p = MAXINT % y;
     unsigned twop = (2*p) %y;
     unsigned amody = a % y;
     unsigned bmody = b % y;
     return addmod(mulmod(amody,twop,y),bmody,y);
   }
}
/*________________________________________________________________________*/

digit mod_digit(bignum x, digit y)
/* compute bignum x modulo a digit y */
{ unsigned int i;
  digit s;
  if (x.ln == 1 )
     return x.val[0] % y;
  else if (x.ln == 2)
     return  mod_digit_aux(x.val[1],x.val[0],y);
  else
     { i= x.ln-2;
       s = x.val[x.ln -1];
       while (i != MAXDIGIT)
          { s = mod_digit_aux(s,x.val[i],y);
            --i;
          }
       return s;
     }
}
/*________   BINARY TO DECIMAL______________________________________*/

bignum btod(bignum x, unsigned n)
/* x is in base 2^16 for 16-bit compilation, or base 2^32 for 32-bit or 64-bit compilation. */
/* returns a bignum base n; usually n = 1000 or 10000   */

{  /* first allocate space.  If x has N digits, x <= B^N where B = 2^16,
      so x <= 10^(3 (16/3 log 2)N)  or 10 ^(4 (4 log 2)N).  We have
      (16/3) log 2 <= 1.60549332  and 4 log 2 <= 1.20411999    */

  bignum ans,t,s;
  unsigned i;
  if (n==1000)
     ans.ln = (unsigned ) (x.ln * 1.6054934 + 1);
  else if (n==10000)
     ans.ln = (unsigned) (x.ln * 1.20412 + 1);
  else
     ans.ln = (digit) (x.ln * (unsigned) sizeof(int) *
         (unsigned)(log10(2.0)/log10((double)n)) + 1);

  ans.ln = 2*ans.ln;

  ans.val = getspace(ans.ln);
   /* generate first digit of answer */

  divide_by_digit(x,n,&s,ans.val);
  for(i=1;i<ans.ln;i++) /* generate i-th digit of answer */
     { if((s.ln > 1) || (s.ln == 1 && s.val[0] != 0))
          { divide_by_digit(s,n,&t,ans.val + i);
            freespace(s.val);
            s = t;
          }
       else
          ans.val[i] = 0;
     }
  freespace(s.val);   /* last one hasn't been freed yet */
   /* now strip off initial zeroes */
  for(i = ans.ln-1; (i != MAXDIGIT && ans.val[i] == 0) ; --i)
     --ans.ln;   /* i !=MAXDIGIT needed to stop loop in case answer is zero */
  if (i==MAXDIGIT)
     ans.ln = 1;
  return ans;
}

/*__________    SUBTRACTION ______________________________________*/

void bigminus2(bignum x, bignum y, bignum *ansp)
/* does not allocate space */
/* you can call bigminus(x,y,&x) safely, overwriting x.val */
/* subtract y from x getting ans */
/* it's assumed y is not greater than x */
{  unsigned i;
   digit borrow = 0;
   ansp->ln = x.ln;
   for(i=0;i< ansp->ln; i++)
      { if (i >= y.ln)
           { if (borrow == 0)
                ansp->val[i] = x.val[i];
             else
                subaux(x.val[i],0,borrow,(ansp->val) + i,&borrow);
           }
        else if (x.val[i] > 0 || borrow == 0)
           subaux(x.val[i],y.val[i],borrow,(ansp->val)+i,&borrow);
        else
           {  /* borrow == 1 && x.val[i] == 0 */
              /* put 0 in for borrow and MAXDIGIT instead of MAXDIGIT+1 */
             subaux(MAXDIGIT,y.val[i],0,(ansp->val)+i,&borrow);
             borrow = 1;
           }
      }
   /* Now strip off initial zeroes */
   for(i=ansp->ln -1; (i!= MAXDIGIT && ansp->val[i]==0 ) ; --i) 
       ; /* empty body of for loop */
   if(i==MAXDIGIT)
      ansp->ln = 1; /* in case answer is zero, don't return length 0*/
   else
      ansp->ln = (unsigned)(i+1);
}
/*__________________________________________________________________*/
void bigminus(bignum x, bignum y, bignum *ansp)
/* allocates space for the answer */
{ ansp->ln = x.ln;
  ansp->val = getspace(x.ln);
  bigminus2(x,y,ansp);
}

/*___________________ DIVISION ______________________________________*/

static void left_shift(bignum x, int i, bignum *y)
/* y is passed unallocated  and will be allocated */
/* given input bignum x, create a new bignum y and make it equal
to x shifted left by i bits  (i<NN).  Note that y may be one longer
than x was. */
{ unsigned j;
  /* Theoretically we should check whether x.ln == (unsigned)(-1),
     but why slow down normal operations for something that will never happen? */
  y ->ln = (unsigned)(x.ln + 1);  /* include room for an extra digit */
  y->val = getspace(y->ln);
  y->val[0] = x.val[0] << i;
  for(j=1;j<x.ln;++j)
     y->val[j]=   (x.val[j] << i) | (x.val[j-1] >> (NN-i));
  y->val[x.ln] = x.val[x.ln-1] >> (NN -i);
  if (y->val[x.ln] == 0)
     y->ln =(unsigned)(y->ln-1);  /* extra digit not needed */
}
/*__________________________________________________________________*/
void right_shift(bignum x, int i, bignum *y)
/* not static, but not EXPORTed either; is called in bigmod.c */
/* y is passed already allocated */
/* given input bignum x, and a pointer y to a bignum with space
already allocated,  make *y equal
to x shifted right by i bits  (i<NN).  Note that y may be one shorter
than x was.  It's OK to have *y = x, in fact it will be normal to
call right_shift(x,i,&x).   */
{ unsigned j;
  for(j=0;j<x.ln-1;++j)
     y->val[j]=   (x.val[j] >> i) | (x.val[j+1] << (NN-i));
  y->val[x.ln-1] = (x.val[x.ln-1] >> i);
  if ((y->val[x.ln-1] == 0) && (x.ln > 1))
     y->ln =(unsigned)(x.ln-1);
  else
     y->ln = x.ln;
}
/*__________________________________________________________________*/

/* divide a bignum x by a digit y, getting a bignum quotient and
   digit remainder.  This is more efficient than converting the digit y
   to a bignum and using bigdivide. */

void divide_by_digit(bignum x, digit y, bignum *q, digit *r)
/* allocates space  for the quotient */
/* but assumes space is already allocated for the  remainder */
{ switch (y>>(NN-1))
     { case 0:   /* left shifting dividend will be necessary */
          q->val = getspace(x.ln+1);
          break;
       case 1:   /* shifting not necessary */
          q->val = getspace(x.ln);
          break;
     }
  divide_by_digit2(x,y,q,r);
}
/*___________________________________________________________________*/
void divide_by_digit2(bignum x, digit y, bignum *q, digit *r)
/* assumes space already allocated */
/* assumes q has room for x.ln digits  if
left-shifting quotient is not necessary and
one more if left-shifting quotient is necessary */
{  unsigned i;
   digit c,d,trialq,test0,test1,product0,product1,rem;
   bignum newx;

/* if x.ln <=2 then we can just use arithmetic on longs */

if (x.ln == 1)
   { q->ln = 1;
     q->val[0] = x.val[0]/y;
     *r = x.val[0] - q->val[0] * y;
     return;
   }
if (x.ln == 2)
   { if(x.val[1] < y)
        { /* one-digit quotient */
          q->ln = 1;
          longdiv(x.val[1],x.val[0],y,&q->val[0],r);
          return;
        }
     /* Now the quotient will be two digits */
     q->ln = 2;
     q->val[1] = x.val[1]/y;
     c = x.val[1] - y * (q->val[1]);
     longdiv(c,x.val[0],y,&q->val[0],r);
     return;
   }

/* Now we can assume x.ln > 2, i.e. we have at least a three-digit dividend.*/

/* first we "normalize" by left-shifting both x and y the same number
of bits until the first bit of y is 1.
See below for the reason why we do that, and
Knuth vol. 2 p. 257 for the proofs.
*/
d= y;
for(i=0;  (d & LEFTDIGIT) != LEFTDIGIT ; ++i)
   d= d<<1; /* i counts the shifts */
if (i != 0)
   { left_shift(x,i,&newx);
     divide_by_digit2(newx,d,q,r);
     *r = (*r >> i);     /* renormalize remainder */
     freespace(newx.val);    /* it was allocated by left_shift */
     return;
   }

/* henceforth we can assume the first bit of y is 1  */
newx.val = getspace(x.ln);
newx.ln = x.ln;
q->ln = x.ln;  /* possibly one too big */
q->val[x.ln-1] = 0;  /* in case it's never written to; it's checked later */
for (i=0; i < x.ln ; i++)
   newx.val[i] = x.val[i];
i = i-2;       /*  =  x.ln - 2  */


/* Entering the following loop, you have just subtracted, and newx represents
the last line of the calculation, without initial zeroes but
possibly with first digit bigger than first digit of y.  The value of i
is newx.ln -2 at the beginning of the loop.  We are going to write
ans.val[i], and possibly ans.val[i+1] in case the first digit of newx is
more than y.  In that case we have previously written
zero there so it's ok to overwrite.
*/

while (i != MAXDIGIT )  /* write i-th digit from right in answer,
                    i.e. power of base^i */

   { if(y <= newx.val[i+1])
        { q ->val[i+1] = 1;
          newx.val[i+1] -=y;
          assert(newx.val[i+1] < y);  /* because y has 1 in the leftmost bit */
        }
     longdiv(newx.val[i+1],newx.val[i],y,&trialq,&rem);
       /*  Multiply back */
     while (1)
        { test0 = newx.val[newx.ln-2];
          test1 = newx.val[newx.ln-1];
          longmult(y,trialq,&product0,&product1);
          /* think of test1,test0 as a two-digit number test,
             and product1,product0 as a two-digit number product.
             We want to write
             if(test < product)
               --trialq;
          */
          if(test1 < product1 || (test1 == product1 && test0 < product0))
             -- trialq;
          else
             { --newx.ln;
               newx.val[newx.ln-1] -= product0;
               break;
             }
        }

     /* You have to go through that while loop AT MOST TWICE!  That's why
        we normalized the divisor.  See Knuth volume 2.  */
     /* Moreover trialq is NEVER too small. */

     q->val[i] = (digit) trialq;   /* write this digit of the answer */
     while((newx.val[i] == 0) && (i != 0 ))
        { --i;
          q->val[i] = 0;
          --newx.ln; /* strip off zeroes*/
        }
     --i;
   }
/* finished, remainder is current value of newx */
/* Now adjust q->ln */
while(q->val[q->ln-1] == 0)
   --q->ln;
*r = newx.val[0];
freespace(newx.val);   /* release temporary workspace */
}
/*_____________________________________________________________*/
bignum long_to_bignum(unsigned long x)
/* convert x to a bignum */
/* presumes x >= 0. */
{ bignum ans;
 if(sizeof(long) > sizeof(digit) && (digit) x != x)
     { ans.ln = 2; 
       ans.val = getspace(2);
       ans.val[0] = (digit) x;
       ans.val[1] = (digit) (x >> (sizeof(digit) * 8));
       return ans;
     }
  ans.ln = 1;
  ans.val = getspace(1);
  ans.val[0] = (digit) x;
  return ans;
}

bignum bigint(unsigned long x)
{ return long_to_bignum(x);  // a synonym 
} 
/*_____________________________________________________________*/
int bigdivide(bignum x, bignum y, bignum *q, bignum *r)
/* allocates space  for the answers */
/* divide a bignum x by a bignum y, getting a bignum quotient and
   remainder.  Returns 0 for success, 2 for division by zero.
*/
{ if( compare(x,y) < 0 )
     { *r = x;
       q->ln = 1;
       q->val = getspace(1);
       q->val[0]=0;
       return 0;
     }
  /* Now we know the divisor is <= the dividend */
  switch (y.val[y.ln-1] >> (NN-1))
     { case 0:   /* left-shifting dividend will be necessary */
          q->val = getspace(x.ln - y.ln +2);
          r->val = getspace(y.ln + 1);
          break;
       case 1:   /* shifting unnecessary */
          q->val = getspace(x.ln - y.ln + 1);
          r->val = getspace(y.ln);
          break;
     }
  return bigdivide2(x,y,q,r);
}
/*_____________________________________________________________*/
 /* bigdivide2 assumes  space is already allocated for the answers.
    It assumes there is space for x.ln - y.ln + 2 digits in the quotient
    if left-shifting the dividend will be necessary, and one less if not,
    even though the actual quotient may be one shorter.
    It assumes there is space for y.ln +1 digits of remainder, in case
    left-shifting is necessary (one more than is ever needed for the
    actual remainder).
*/

int bigdivide2(bignum x, bignum y, bignum *q, bignum *r)
/* return 2 for attempted division by zero, 0 for success */

{  unsigned i, oldi, k, stash_length;
   digit d,rem,trialq=0; // initialization silences a warning
   int test;
   bignum bigtrialq;
   bignum newx, newy;
   bignum subtrahend;
   bignum ans;
   bigtrialq.val = NULL;

/* first we dispose of the simpler cases: */
if(y.ln == 1 && y.val[0] == 0)
  return 2;  /* attempted division by zero */
test = compare(x,y);
if(test == 0)  /* x and y are equal, return 1 as a bignum */
   { r->val[0] = 0;
     r->ln = 1;
     q->ln = 1;
     q->val[0] = 1;
     return 0;
   }
if(compare(x,y)== -1)   /*  x < y, dividend < divisor */
   { q->ln = 1;
     q->val[0] = 0;   /* quotient is zero */
     r->ln = x.ln;
     memcpy(r->val,x.val,x.ln * DIGITSIZE);  /* remainder = dividend */
     return 0;
   }

if(y.ln == 1)   /* one-digit divisor */
   { divide_by_digit2(x,y.val[0],q,&d);
     r->val[0] = d;
     r->ln = 1;
     return 0;
   }
if(x.ln == 1)  /* one-digit dividend, at least 2-digit divisor */
   { q->val[0] = 0;
     q->ln =1;
     r->ln = x.ln;
     memcpy(r->val,x.val,x.ln *DIGITSIZE);   /* return copy of x for r */
   }

/* Now the dividend and divisor are both at least 2 digits */

/* first we "normalize" by left-shifting both x and y the same number
of bits until the first bit of y is 1.
See below for the reason we do that , and Knuth vol. 2 p. 257 for the proofs.
*/

d= y.val[y.ln-1];  /* most significant digit of divisor */
if(d == 0)
   assert(0);
for(i=0; (d & LEFTDIGIT) != LEFTDIGIT; ++i)  d= d<<1;   /* i counts the shifts */
if (i != 0)
   { left_shift(x,i,&newx);
     left_shift(y,i,&newy);
     bigdivide2(newx,newy,q,r);
     /* here we may need one extra digit for r, since newy is larger than y */
     right_shift(*r,i,r);        /* renormalize remainder */
     freespace(newx.val);            /* release working space allocated by `left_shift' */
     freespace(newy.val);
     return 0;
   }

/* henceforth we can assume the highest bit of y is 1  */

/* Initialize newx (which will represent the bottom line of the
   calculation so far) to x. */

newx.ln = x.ln;
newx.val = getspace(newx.ln);    /* get working space */
ans.ln = (unsigned)(x.ln - y.ln + 1);  /* possibly one too big */
ans.val = q->val;    /* already allocated space */
ans.val[(unsigned) (ans.ln-1)]= 0;  /* something may be there from the last time it
             was used; other digits will be written over or never examined,
             but this particular digit is checked later and perhaps not
             written into, so must be initialized to zero. */
for (i=0; i < x.ln ; i++)
   newx.val[i] = x.val[i];
i = x.ln -y.ln - 1;   /* first digit of quotient will be i-th one
                         if first digit of x < first digit of y
                         otherwise i+1 -st  */
subtrahend.ln = newx.ln;
subtrahend.val = getspace(newx.ln+2);
 /* more working space; +2 because bigmult2 expects as much space
    as the sum of the lengths of its arguments, and subtrahend is
    going into bigmult2 in a few lines from now
 */

/* Entering the following loop, you have just subtracted, and newx represents
the last line of the calculation, without initial zeroes but
possibly with first digit bigger than first digit of y. The value of i
is correctly set before beginning the loop:  we are going to write
ans.val[i], and possibly ans.val[i+1] in case the first digit of newx is
more than the first digit of y.  In that case we have previously written
zero there so it's ok to overwrite.  At the end of the loop i has to be
incremented appropriately if the new value of newx is much shorter than
the old value.
*/

while ((i != MAXDIGIT) && (newx.ln >= y.ln) )  /* write i-th digit from right in answer,
                    i.e. power of base^i */
   { if(y.val[y.ln-1] <= newx.val[i+y.ln])
        { /* two-digit trial quotient */
          /* Compute that trial quotient as a bignum */
          bigtrialq.ln = 2;
          if(bigtrialq.val)
             freespace(bigtrialq.val);
          bigtrialq.val = getspace(2);
          bigtrialq.val[1] = 1; /* Since the leftmost bit of y is 1 */
          longdiv(newx.val[i+y.ln]-y.val[y.ln-1],newx.val[i+y.ln-1],y.val[y.ln-1],&bigtrialq.val[0],&rem);
          bigmult2(y,bigtrialq,&subtrahend);  /* multiply back */
        }
     else
        { /* one-digit trial quotient */
          longdiv(newx.val[i+y.ln],newx.val[i+y.ln-1],y.val[y.ln-1],&trialq,&rem);
          mult_by_digit2(y, trialq,&subtrahend);  /* multiply back */
          bigtrialq.ln = 0;  /* bigtrialq will not be used. */
        }

     /*  compare to the first y.ln + 1 digits of newx */

     newy.ln = (unsigned)(y.ln + 1);
     newy.val = newx.val + newx.ln -y.ln -1;  /* pointer arithmetic */
                         /* makes newy a bignum consisting of the most
                         significant y.ln + 1 digits of newx */
     while ((test = compare(subtrahend,newy)) > 0 )  /* subtrahend too big,
                                          must decrease trialq */

        { if(bigtrialq.ln == 0)
             { --trialq;
               mult_by_digit2(y, trialq, &subtrahend);
             }
          else if(bigtrialq.val[0])
             { --bigtrialq.val[0];
               bigmult2(y,bigtrialq, &subtrahend);
             }
          else  /* bigtrialq was [1,0]  */
             { freespace(bigtrialq.val);
               bigtrialq.val = NULL;
               trialq = MAXDIGIT;
               mult_by_digit2(y,trialq,&subtrahend);
               bigtrialq.ln = 0 ;  // BUG --this line omitted until 3.26.04 
             }
        }

    /* You have to go through that while loop AT MOST TWICE!  That's why
       we normalized the divisor.  See Knuth volume 2.  */

    /* Moreover trialq is NEVER too small. */
     if(bigtrialq.ln == 0)
        { ans.val[i] = (digit) trialq;   /* write this digit of the answer */
        }
     else
        { ans.val[i] = bigtrialq.val[0];
          ans.val[i+1] = bigtrialq.val[1];
        }
     oldi = i;
     stash_length = newy.ln;
     bigminus2(newy,subtrahend,&newy);  /* use same space for newy */
     /*  Since the digits of newy are occupying the same space as the
         leftmost digits of newx, this alters the digits of newx
         appropriately.  However, it does not adjust newx.ln, although
         it does adjust newy.ln.   We must therefore adjust newx.ln
         manually:   */
     newx.ln = (unsigned)(newx.ln - stash_length + newy.ln);
     /* This is fine unless newy is zero; but in that case newx.ln should
     be decreased still more:  */
     while(newx.val[newx.ln-1] == 0 && newx.ln > 1)
        --newx.ln;     /* 1 is the smallest it can get */
                       /* Next update i to where we will write next time;
                          more accurately (since we may write to digit i or i+1),
                          initialize i for next time through the loop */
     i = y.ln < newx.ln ? newx.ln - y.ln - 1 : MAXDIGIT;
     /* Now perhaps i is MAXDIGIT if
        newy is a good bit shorter than it was before we took subtrahend away. */

     for(k = oldi -1; k >= i+1 && k !=MAXDIGIT; --k)
        ans.val[k] = 0; /* fill in zeroes                         */
                        /* this works even if i = MAXDIGIT, so i+1 = 0 */
   }
/* Not necessarily finished yet; we may have i=MAXDIGIT, and newx still greater
   than or equal to y so the last digit of the quotient (which has been written as 0)
   still needs to be overwritten. */
if( i == MAXDIGIT )
   { test = compare(newx,y);
     if (test > 0)
        { ans.val[0] = 1;
          bigminus2(newx,y,&newx);
        }
     else if (test == 0)
        { newx.ln = 1;
          newx.val[0] = 0;
          ans.val[0]=1;
        }
   }

/* Now we still have to adjust ans.ln; it may be one too long as
   remarked above. */

if ((ans.val[ans.ln-1] == 0) && (ans.ln != 1))
   --ans.ln;
/* Now we have to copy the remainder into the given space r->val */

r->ln = newx.ln;
memcpy(r->val,newx.val,newx.ln *DIGITSIZE);
q->ln = ans.ln;         /* q->val is already ans.val */
freespace(subtrahend.val);  /* release working space */
freespace(newx.val);
if(bigtrialq.val)
   freespace(bigtrialq.val);
return 0;
}

/*________ EXPONENTIATION __________________________________*/

int bigpower(bignum x, digit d, bignum *ansp)
/* return zero for success;
   return 1 if the answer would require more digits than can be
   represented in an unsigned int (if sizeof(int) < sizeof(long)),
   or in a  signed int (if sizeof(int) == sizeof(long)).  That is,
   if the NUMBER of digits is more than 2^32.   
*/
/* x^d = ans; allocates space for ans */

{ unsigned bits;  /* how many bits in d */
  unsigned int i;
  unsigned long s;
  unsigned c;
  bignum t;
             /* next line  computes how many bits in most sig. digit of x*/
  /* Visual C++ compiler enters an infinite loop on the following lines even though
     the Visual C debugger shows that what's inside the while loop is zero!  */
  for(bits = 0; bits <= NN; ++bits)
     { c = x.val[x.ln-1] >> bits;
       if(c==0)  /* assign the >> expression to a variable to avoid Visual C
                 bug with a >> expression inside an if */
          break;
     }
  bits += NN * (x.ln -1);
  if (d==0)
     { ansp->ln = 1;
       ansp->val = getspace(1);
       ansp->val[0] = 1;
       return 0;  /* signalling success */
     }
      /* first compute the length of the answer;
         make it a long so as to detect overflow */
  s = (unsigned long) d * (unsigned long) bits;  /* length in bits */
  s = s/NN + 1; /* length in digits */
  if ( (s >> (NN-1)) != 0 )
     return 17;  /* signalling overflow to calling routine;
                    17 gets the appropriate message from aem() */
  ansp->ln = (unsigned) s;
  ansp->val = getspace(ansp->ln + 2);
    /* The extra 2 so that we always have enough space going into bigmult */

        /* Now do the recursive computation */

  if (d==1)
     { ansp->ln = x.ln;
       for(i=0;i<ansp->ln;++i)
          ansp->val[i] = x.val[i];
       return 0;
     }
  if ((d & 0x0001) == 0 )    /* d is even */
     { bigpower(x, d>>1, &t);  /* allocates space for t.val */
       bigmult2(t,t,ansp);
       freespace(t.val);
       return 0;
     }
  else    /* d is odd */
     { bigpower(x, d-1, &t);
       bigmult2(t,x,ansp);
       freespace(t.val);
       return 0;
     }
}
/*________  SQUARE ROOT ___________________________________________*/

int bigsqrt(bignum x, bignum *ansp, bignum *remp)
/*  ans points to  the greatest integer in sqrt(x) */
/*  rem points to  the remainder, that is, x - *ansp^2, so you can 
test whether it's an exact root by checking for *remp == 0. */
/*  Space will be allocated for both *ansp and *remp  */

{ ansp->val = getspace(x.ln /2 + 1);
  remp->val = getspace(x.ln);
  return bigsqrt2(x,ansp,remp);
}
/*________________________________________________________________*/
int bigsqrt2(bignum x, bignum *ansp, bignum *remp)
/*  ans points to  the greatest integer in sqrt(x) */
/*  rem points to  the remainder, that is, x-*ans^2 */
/*  assumes space is already allocated */

{
bignum teven,todd;
bignum temp,rem,temp2;
unsigned i,j;
teven.val = getspace((x.ln / 2) + 1);
todd.val  = getspace((x.ln / 2) + 1);
temp.val  = getspace(x.ln + 2);
temp2.val  = getspace(x.ln + 2);
rem.val  = getspace(x.ln + 2 );

/* initialize teven to an approximation to sqrt x */
if(x.ln & 1)  /* length of x is odd */
   { teven.ln = (unsigned)( (1 + x.ln)/2);
     teven.val[teven.ln -1] = (digit) sqrt((double) x.val[x.ln-1]);
   }
else
   { teven.ln = (unsigned)( x.ln/2);
     { double z = sqrt((double) x.val[x.ln-1]);
       int exponent;
       double mantissa;
       /* multiply by 2^(NN/2) */
       mantissa = frexp(z,&exponent);
       exponent += NN/2;
       teven.val[teven.ln-1] = (digit) ldexp(mantissa,exponent);
     }
   }
for(i=0; i < teven.ln -1; i++)
   teven.val[i] = 0;
      /* that completes the initialization of teven */

for(i=0;     ; i++)
   { int flag;
     if(i & 1)
        { bigdivide2(x,todd,&temp,&rem);
          bigplus2(temp,todd,&temp2);
          flag = temp2.val[0] & 1;
          right_shift(temp2,1,&teven);
        }
     else
        { bigdivide2(x,teven,&temp,&rem);
          bigplus2(temp,teven,&temp2);
          flag = temp2.val[0] & 1;
          right_shift(temp2,1,&todd);
        }
     if (! compare(todd,teven))   /* finished */
        { ansp->ln = teven.ln;
          for (j=0; j< ansp->ln; j++)
             ansp->val[j] = teven.val[j];
          if(flag)
             bigplus2(rem,i&1 ? todd : teven,&rem);          
          remp->ln = rem.ln;
          for (j=0; j< remp->ln; j++)   
             remp->val[j] = rem.val[j];
          freespace(teven.val);
          freespace(todd.val);
          freespace(temp.val);
          freespace(temp2.val);
          freespace(rem.val);
          return 0;
        }
   }
}
/*________________ ROOT_____________________________________________*/
int bigroot(unsigned n, bignum x, bignum *ansp, bignum *remp)
/* allocate space and compute greatest integer in the n-th root of x,
making remp point to the remainder of x on division by (*ansp)^n.
(This number isn't interesting except that you can use it to see if the
root was exact or not.)  */
/* return 0 for success, 1 for out of space */
/* return 2 for n too large (15 bits is the maximum) */

{   ansp->val = getspace(x.ln/n + 1);
    remp->val = getspace(x.ln);
    return bigroot2(n,x,ansp,remp);
}
/*_____________________________________________________________*/
int bigroot2(unsigned n, bignum x, bignum *ansp, bignum *remp)
/* space is already allocated for *ansp and *remp */
/* exit conditions on ans and *remp are specified in bigroot above */
/* Use Newton's method;  nextguess = [(n-1) * old + (x/ old^(n-1))]/n */
/* For an initial guess, knock off digits in groups of n */

{ bignum teven,todd,rem;
  bignum temp, temp2;
  bignum *old,*next;
  unsigned i,j;
  long p;
  unsigned k,u;
  if(n >> (NN-1))
     return 2;
  teven.val = getspace(x.ln+1);  /* workspace */
  todd.val =getspace(x.ln+1);
  rem.val = getspace(x.ln+1);
  temp2.val = getspace(x.ln+1);
  /* initialize teven to an approximation to root(n,x) */
  k = x.ln / n;  /* teven will have k trailing zero digits */
  if(x.ln % n == 0)
    --k;            
  p =  (((long) x.ln - ((long) n)*k) * NN)/n;
    /* p is an upper bound for the number of bits in the leading part of teven */
  j = (unsigned) p;  
  if(j==0)
     assert(0);   // because of --k above, it can't be zero.
  u = j/NN + 1; /*number of digits required for those bits */
  /* make teven have its least significant k digits 0 and its next u
  digits containing 2^j approximately */
  teven.ln = (unsigned)(k + u);  /* never mind checking k+u for overflow*/
  for(i=0;i<k + u -1;i++)
     teven.val[i] = 0;
  teven.val[k+u-1] =  (j % NN) ? (1 << (j % NN)) : 1;

  /* that finishes initializing teven to an approximation to root(n,x) */
  for(i=0; ; i++)
     { if(i & 1)
          { old = &todd;
            next = &teven;
          }
       else
          { old = &teven;
            next = &todd;
          }
       bigpower(*old,n-1,&temp);  /* allocates temp.val */
       bigdivide2(x,temp,&temp2,&rem);
       if(!compare(*old,temp2))
          { /* finished, it's an exact root */
            remp->ln = 1;
            remp->val[0] = 0;
            ansp->ln = old->ln;
            for(j=0; j<ansp->ln; j++)
               ansp->val[j] = old->val[j];
            freespace(temp.val);
            freespace(temp2.val);
            freespace(rem.val);
            freespace(teven.val);
            freespace(todd.val);
            break;
          }
       if(!compare(todd,teven))
          { /* finished, it's not an exact root */
            bigmult2(*old,temp,&temp2);  /* n-th power of the answer */
            bigdivide2(x,temp2,&temp,remp);
            ansp->ln = old->ln;
            for(j=0; j<ansp->ln; j++)
               ansp->val[j] = old->val[j];
            freespace(temp.val);
            freespace(temp2.val);
            freespace(rem.val);
            freespace(teven.val);
            freespace(todd.val);
            break;
          }
       freespace(temp.val);  /* allocated by bigpower */     
       temp.val = getspace(x.ln+1);
       mult_by_digit2(*old,n-1,&temp);
       bigplus2(temp,temp2,&temp);
       divide_by_digit(temp,n,next,&k);
     }
  return 0;
}

/*_________   GREATEST COMMON DIVISOR _____________________________*/
/* Lehmer's gcd,  algorithm L p. 329 Knuth volume 2 */
/* Does not try to use single-precision arithmetic on small u,v  */
/* Return answer in fresh space */
/* calls shortshiftgcd when you get down to digits */

void biggcd(bignum x, bignum y, bignum *ans)
{ digit uhat, vhat,q,scratch, aa;
  long a,b,c,d,t,den1,den2;
  bignum tt,w,r,qq,u,v;
  int err;
  unsigned long max = 0xffffffffUL;
  err = compare(x,y);
  if(err < 0)  /* x < y */
     { biggcd(y,x,ans);
       return;
     }
  if(err==0)  /* x == y */
     { ans->val = getspace(x.ln + 1);
       memcpy(ans->val,x.val, x.ln*DIGITSIZE);
       ans->ln = x.ln;
       return;
     }
     /* Now x >= y */
  u.ln = x.ln;
  u.val = getspace(u.ln + 1);
  v.val = getspace(u.ln + 1);
  tt.val = getspace(u.ln + 1);
  qq.val = getspace(u.ln + 1);
  w.val = getspace(u.ln + 1);  /* make workspace */
  r.val = getspace(u.ln + 1);
  memcpy(u.val,x.val,u.ln *DIGITSIZE);
  v.ln = y.ln;
  memcpy(v.val,y.val,v.ln *DIGITSIZE);
  while(u.ln > 1 && v.ln > 1)
     { uhat = u.val[u.ln -1];
       vhat = (v.ln == u.ln ?  v.val[v.ln-1] : 0);
       a=d=1;
       b=c=0;  /* end of step L1 */
       while(1)  /* step L2; we exit by 'break' to L4 */
          { den1 = vhat + c;
            den2 = vhat + d;
            if((den1 & max) == 0 || (den2 & max) == 0)   /* only possible overflow value */
               break;    /* go to L4 */
            q= (digit) ((uhat+a)/den1);
            if(q != (uhat + b)/den2)
               break;  /* That is, go to L4 */
            t = a - q*c;     /* Step L3 */
            a = c;
            c = t;
            t = b - q*d;
            b = d;
            d = t;
            t = uhat - q*vhat;
            uhat = vhat;
            vhat = (digit) t;
          }
       if(b==0)  /* step L4 begins */
          { bigdivide2(u,v,&qq,&tt);   /* u >= v as bigdivide2 requires */
            u.ln = v.ln;
            memcpy(u.val,v.val,u.ln *DIGITSIZE);
            v.ln = tt.ln;
            memcpy(v.val,tt.val, v.ln *DIGITSIZE);
          }
       else
          { if(a < 0 && b >= 0)
               { mult_by_digit2(u,(digit) -a,&tt);
                 mult_by_digit2(v,(digit) b,&r);
                 bigminus2(r,tt,&tt);
               }
            else if( a >= 0 && b < 0)
               { mult_by_digit2(u,(digit) a,&tt);
                 mult_by_digit2(v,(digit) -b,&r);
                 bigminus2(tt,r,&tt);
               }
            else  /* they are both nonnegative */
               { mult_by_digit2(u,(digit) a,&tt);
                 mult_by_digit2(v,(digit) b,&r);
                 bigplus2(r,tt,&tt);
               }
            if(c < 0 && d >= 0)
               { mult_by_digit2(u,(digit) -c,&w);
                 mult_by_digit2(v,(digit) d,&qq);
                 bigminus2(qq,w,&w);
               }
            else if( c >= 0 && d < 0)
               { mult_by_digit2(u,(digit) c,&w);
                 mult_by_digit2(v,(digit) -d,&qq);
                 bigminus2(w,qq,&w);
               }
            else  /* they are both nonnegative */
               { mult_by_digit2(u,(digit) c,&w);
                 mult_by_digit2(v,(digit) d,&qq);
                 bigplus2(qq,w,&w);
               }
            u.ln = tt.ln;   /* u = tt makes them share digit space from now on */
            memcpy(u.val,tt.val,u.ln *DIGITSIZE);
            v.ln = w.ln;
            memcpy(v.val,w.val,v.ln * DIGITSIZE);
          }
     }
  if(v.ln == 1 && v.val[0] == 0)
     { ans->val = getspace(u.ln);
       ans->ln = u.ln;
       memcpy(ans->val,u.val,u.ln *DIGITSIZE);
       return;
     }
  if(u.ln > 1)  /* and v.ln == 1 */
     { divide_by_digit2(u,v.val[0],&tt,&scratch);
       aa = scratch;
     }
  else
     aa = u.val[0];
  ans->val = getspace(1);
  ans->ln = 1;
  ans->val[0] = shortshiftgcd(aa,v.val[0]);
  freespace(tt.val);
  freespace(w.val);
  freespace(r.val);
  freespace(qq.val);
}

/*_______________________________________________________________________*/

char * bignum_string(bignum x, int separator)
/* convert binary bignum to a string, allocated by callocate,
suitable for display.  */
/*  separator controls the format:
            0      blocks of 6 (ordinary decimal) digits separated by space
            1      no separation of digits
            2      blocks of 3 (ordinary decimal) digits separated by comma
            n > 2  blocks of 3 (ordinary decimal) digits separated by
                   the symbol with ascii code n, e.g. period or space
*/
{ bignum decimal;
  char *ans;
  unsigned int i;
  char *marker;
  decimal = btod(x,1000);
  if(decimal.ln==0)
     return NULL;  /* no space */
  ans = callocate(decimal.ln * 4 + 1, sizeof(char));
  if (ans == NULL)
     { freespace(decimal.val);
       return NULL;   /* no space */
     }
  i = decimal.ln-1;
  marker = ans;
  sprintf(ans,"%d",decimal.val[i]);
  --i;
  while(*marker)
     ++marker;
            /* now marker points to the null after the first digit */
  if(decimal.ln == 1)
     return ans;  /* stop, you're done */
  if(separator == 2 )
     { *marker = ',';
       ++ marker;
     }
  if(separator == 0 &&  !(i & 1) )  /* i is even and we want blocks of 6 digits */
     { *marker = 32;
       ++marker;
     }
  if(separator > 2)
     { *marker = separator;
       ++marker;
     }
  while(i!=MAXDIGIT)  /* convert the i-th digit */
   { sprintf(marker,"%03d",decimal.val[i]);
     marker += 3;
     /* Now do we need a separator? */
     if( separator==0 && !(i&1) && i !=0 )
        { *marker = 32;
          ++marker;
        }
     if( separator==2 && i != 0)
        { *marker = ',';
          ++marker;
        }
     if(separator > 2 && i != 0)
        { *marker = separator;
          ++marker;
        }
     --i;
   }
   *marker = '\0';   /* terminate the string */
   freespace(decimal.val);  /* no longer needed */
   return ans;
}

/*_________________________________________________*/
#ifndef _Windows
int convert_and_print(bignum x, int separator)
/* convert binary bignum to decimal and print directly */
/*  separator controls the format as above */

{ char *ans;
  ans = bignum_string(x,separator);
  if(ans)
     { printf("%s",ans);
       freespace(ans);
       return 0;
     }
  return 1;  /* no space */
}
#endif
/*_____________________________________________________________*/
/* This decimal-to-binary conversion uses a quadratic amount of space,
but it's ok since we only use it to process bignums that have been
typed in, so they can't be very long. */

int string_bignum(char *s, unsigned n, bignum *xp)
/* convert a string of n decimal digits to a bignum, allocating space */
/* string doesn't have to be null-terminated */

{ unsigned i;
  bignum aux, aux2, addit;
  char p[5];
  char *endptr;
  char t[5];
  if (n < 5)     /* it will convert to a digit */
     { xp->ln = 1;
       for(i=0; i<n; i++)
          p[i] = s[i];
       p[n] = '\0';
       xp->val = getspace(1);
       xp->val[0] = (digit) strtoul(p,&endptr,10);
       return 0;  /* finished */
     }
  if( string_bignum(s,n-4,&aux) != 0 )  /* allocating space for aux */
     return 1;  /* error */
  addit.ln = 1;
  addit.val = getspace(1);
  for(i=0; i<4; i++)
     t[i] = s[n-4+i];   /* last four decimal digits of s */
  t[4] = '\0';
  addit.val[0] = (digit) strtoul(t,&endptr,10);
  mult_by_digit(aux, 10000, &aux2);
  freespace(aux.val);
  bigplus(aux2, addit,xp);
  freespace(aux2.val);
  freespace(addit.val);
  return 0;
}
/*____________________________________________________________*/
int bigfactorial(unsigned int n, bignum *ans)
/* compute n! */
/* return value 1 is out of space;
   return value 2 is answer too big (needs more than sizeof(int) for
   the number of digits)
   return value 0 is success
*/
/* How many digits are needed to hold n! ?
By Stirling's formula, the number of digits base 2 in n! is at
most, with log meaning log to the base 2,
(1/2) log(2npi) + n (log n - 1)  + log(1 + (1/(12n-1))),
according to CRC tables, p. 387 12th edition.  Since  log(1+x) < x,
for positive x,  the number of digits is at most
(1/2) log 2pi  +  log n + n (log n - 1) + 1/(12n -1)
which is less than
(3/2) + k + n(k-1) + 1 where k = number of digits in n
which is less than
3 + k + n(k-1).   For simplicity, that is bounded by
nk so long as n-k>3, which it certainly is for n>10. */

{ bignum temp1,temp2;
  unsigned int k,i;
  unsigned long s;
  if(n < 9)
     { ans->val = getspace(1);
       ans->ln = 1;
       switch(n)
          { case 0: ans->val[0] = 1; return 0;
            case 1: ans->val[0] = 1; return 0;
            case 2: ans->val[0] = 2; return 0;
            case 3: ans->val[0] = 6; return 0;
            case 4: ans->val[0] = 24; return 0;
            case 5: ans->val[0] = 120; return 0;
            case 6: ans->val[0] = 720; return 0;
            case 7: ans->val[0] = 5040; return 0;
            case 8: ans->val[0] = (digit) 40320UL;
                    return 0;
          }
     }
  k=0;
  while(n>>k)
    ++k;
  /* Now k is the bitlength of n */
  s = n * k;
  if(s >> 16)
     return 2;  /* answer too big to compute */
    /* s is the BIT length; now we want the length in DIGITS */

  s = s>>5;  /* a 32-bit machine */
  temp1.val = getspace((digit) s);  /* workspace */
  temp2.val = getspace((digit) s);  /* more workspace */
  temp1.ln = 1;
  if(n&1)
     { temp1.val[0]=n;
       temp1.ln = 1;
     }
  else
     { temp2.val[0]=n;
       temp2.ln = 1;
     }
  for(i=n-1;i > 1; i--)
     { if( i & 1)
          mult_by_digit2(temp2,i,&temp1);
       else
          mult_by_digit2(temp1,i,&temp2);
     }
  *ans = temp2;
  freespace(temp1.val);
  return 0;
}
/*________________________________________________________________________*/
int bignum_double(bignum x, double *ans)
/* convert a bignum to a double unless it's too big */
/*  bignum must have at least two digits */
/* return value 0 means success; 1 means failure */
/* doesn't care if bignums use 16-bit or 32-bit digits */

{  double mantissa,base;
   int exponent,exp2;
   if (x.ln > 65)
      return 1;  /* certainly too big */
   if(x.ln == 1)
      { *ans = (double) x.val[0];
        return 0;
      }
   base = pow(2.0,NN);
   if(x.ln == 2)
      { *ans = x.val[1] * base + x.val[0];
        return 0;
      }
   /* With 52-bit mantissas and 32-bit digits, 2 digits is enough; but
      we include the next line in case we switch to long doubles at some
      future time; then this won't need modification. */
   if(x.ln == 3)
      { *ans = (x.val[2] *base + x.val[1]) * base + x.val[0];
        return 0;
      }
   *ans = (x.val[x.ln-1]*base + x.val[x.ln-2]) *base + x.val[x.ln-3];
   exponent = (int ) (NN * (x.ln - 3));
   if(exponent < 0)
       return 1;   /* assert(0) */
   if(exponent == 0)
      return 0;
   mantissa = frexp(*ans,&exp2);
   exponent += exp2;
   if(exponent > 1023)  /* 1023 = maximum exponent of a double */
      return 1;
   *ans = ldexp(mantissa,exponent);
   return 0;
}

/*________________________________________________________________________*/
int bigrat_double(bignum p, bignum q, double *ans)
/* convert p/q to a double if possible, returning 0 for success;
succeed even if p and q are individually too large to convert to double;
fail only if the ratio is too big.  On failure ans is garbage and
1 is returned.  */

{ double temp,num,denom;
  int err,exp;
  unsigned diff, dd;
  unsigned num_discard,denom_discard;
  if(p.ln < q.ln || (p.ln == q.ln && p.val[p.ln-1] < q.val[p.ln-1]))
      { err = bigrat_double(q,p,&temp);
        if(err)
           return err;
        if(temp == 0.0)
           return 1;
        *ans = 1/temp;
        return 0;
      }
  /* Now q <= p */
  diff = p.ln - q.ln;
  dd = 308/NN;
  if(diff > dd)
      return 1;
  denom_discard =  q.ln < 7 ? 0 : q.ln - 6;
  num_discard = p.ln < 7 ? 0 : p.ln - 6;
  p.val += num_discard;  /* affects only local copy of p */
  q.val += denom_discard;  /* affects only local copy of q */
  /* Now q and q are short enough to convert to doubles; they are
      5 digits long which is 81-96 or 161-192 bits (depending if
      digits are 16 or 32 bits) but in either case is MORE accuracy
      than the 80-bit coprocessor and LESS than the range of a double
      (which is 10^308  > 2^192)
  */
  bignum_double(p,&num);
  bignum_double(q,&denom);
  temp = num/denom;
  frexp(temp,&exp);
  exp += num_discard-denom_discard;
  if(exp > 1023)
     return 1;
  *ans = ldexp(temp,exp);
  return 0;
}
/*_______________________________________________________________________*/
static unsigned shortshiftgcd(unsigned u, unsigned v)
/* There is a copy of this in arith.c */
/* Change it too if this changes */
/* return gcd(u,v) but not lambda and mu */
/* binary method, no division:  Algorithm B */
/* Adapted to use unsigned, so as to double the input capacity
   and avoid portability problems from right-shifting signed ints */
{ short k;
  k=0;
  while (!(u&1) && !(v&1))
     { ++k;
       u >>= 1;
       v >>=1;
     }
  while(u != 0 && v != 0)
     { if(!(u&1))
          { while(!(u&1))
              u >>= 1;
          }
       else
          { while(!(v&1))
               v >>= 1;
          }
       /* At this point both u and v are odd */
       if(u > v)
          u -= v;
       else
          v -= u;
       /* Now one is odd and one is even */
     }
  if(u==0)
     u=v;
  return u * (1 << k);
}

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists