home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / gnustuff / tos / g__~1 / gplibs15.zoo / xinteger.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-01  |  48.6 KB  |  2,419 lines

  1. /* 
  2. Copyright (C) 1988 Free Software Foundation
  3.     written by Doug Lea (dl@rocky.oswego.edu)
  4.  
  5. This file is part of the GNU C++ Library.  This library is free
  6. software; you can redistribute it and/or modify it under the terms of
  7. the GNU Library General Public License as published by the Free
  8. Software Foundation; either version 2 of the License, or (at your
  9. option) any later version.  This library is distributed in the hope
  10. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  11. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  12. PURPOSE.  See the GNU Library General Public License for more details.
  13. You should have received a copy of the GNU Library General Public
  14. License along with this library; if not, write to the Free Software
  15. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  16. */
  17.  
  18. /*
  19.   Some of the following algorithms are very loosely based on those from 
  20.   MIT C-Scheme bignum.c, which is
  21.       Copyright (c) 1987 Massachusetts Institute of Technology
  22.  
  23.   with other guidance from Knuth, vol. 2
  24.  
  25.   Thanks to the creators of the algorithms.
  26. */
  27.  
  28. #ifdef __GNUG__
  29. #pragma implementation
  30. #endif
  31. #include <xinteger.h>
  32. #include <std.h>
  33. #include <ctype.h>
  34. #include <math.h>
  35. #include <limits.h>
  36. #include <xobstack.h>
  37. #include <xallocri.h>
  38. #include <new.h>
  39. #include <builtin.h>
  40.  
  41. /*
  42.  Sizes of shifts for multiple-precision arithmetic.
  43.  These should not be changed unless Integer representation
  44.  as unsigned shorts is changed in the implementation files.
  45. */
  46.  
  47. #define I_SHIFT         (sizeof(short) * CHAR_BIT)
  48. #define I_RADIX         ((unsigned long)(1L << I_SHIFT))
  49. #define I_MAXNUM        ((unsigned long)((I_RADIX - 1)))
  50. #define I_MINNUM        ((unsigned long)(I_RADIX >> 1))
  51. #define I_POSITIVE      1
  52. #define I_NEGATIVE      0
  53.  
  54. /* All routines assume SHORT_PER_LONG > 1 */
  55. #define SHORT_PER_LONG  ((unsigned)(((sizeof(long) + sizeof(short) - 1) / sizeof(short))))
  56. #define CHAR_PER_LONG   ((unsigned)sizeof(long))
  57.  
  58. /*
  59.   minimum and maximum sizes for an IntRep
  60. */
  61.  
  62. #define MINIntRep_SIZE   16
  63. #define MAXIntRep_SIZE   I_MAXNUM
  64.  
  65. #ifndef MALLOC_MIN_OVERHEAD
  66. #define MALLOC_MIN_OVERHEAD 4
  67. #endif
  68.  
  69. IntRep _ZeroRep = {1, 0, 1, {0}};
  70. IntRep _OneRep = {1, 0, 1, {1}};
  71. IntRep _MinusOneRep = {1, 0, 0, {1}};
  72.  
  73.  
  74. // utilities to extract and transfer bits 
  75.  
  76. // get low bits
  77.  
  78. inline static unsigned short extract(unsigned long x)
  79. {
  80.   return x & I_MAXNUM;
  81. }
  82.  
  83. // transfer high bits to low
  84.  
  85. inline static unsigned long down(unsigned long x)
  86. {
  87.   return (x >> I_SHIFT) & I_MAXNUM;
  88. }
  89.  
  90. // transfer low bits to high
  91.  
  92. inline static unsigned long up(unsigned long x)
  93. {
  94.   return x << I_SHIFT;
  95. }
  96.  
  97. // compare two equal-length reps
  98.  
  99. inline static int docmp(const unsigned short* x, const unsigned short* y, int l)
  100. {
  101.   int diff = 0;
  102.   const unsigned short* xs = &(x[l]);
  103.   const unsigned short* ys = &(y[l]);
  104.   while (l-- > 0 && (diff = (*--xs) - (*--ys)) == 0);
  105.   return diff;
  106. }
  107.  
  108. // figure out max length of result of +, -, etc.
  109.  
  110. inline static int calc_len(int len1, int len2, int pad)
  111. {
  112.   return (len1 >= len2)? len1 + pad : len2 + pad;
  113. }
  114.  
  115. // ensure len & sgn are correct
  116.  
  117. inline static void Icheck(IntRep* rep)
  118. {
  119.   int l = rep->len;
  120.   const unsigned short* p = &(rep->s[l]);
  121.   while (l > 0 && *--p == 0) --l;
  122.   if ((rep->len = l) == 0) rep->sgn = I_POSITIVE;
  123. }
  124.  
  125.  
  126. // zero out the end of a rep
  127.  
  128. inline static void Iclear_from(IntRep* rep, int p)
  129. {
  130.   unsigned short* cp = &(rep->s[p]);
  131.   const unsigned short* cf = &(rep->s[rep->len]);
  132.   while(cp < cf) *cp++ = 0;
  133. }
  134.  
  135. // copy parts of a rep
  136.  
  137. static inline void scpy(const unsigned short* src, unsigned short* dest,int nb)
  138. {
  139.   while (--nb >= 0) *dest++ = *src++;
  140. }
  141.  
  142. // make sure an argument is valid
  143.  
  144. static inline void nonnil(const IntRep* rep)
  145. {
  146.   if (rep == 0) 
  147.     (*lib_error_handler)("Integer", "operation on uninitialized Integer");
  148. }
  149.  
  150. // allocate a new Irep. Pad to something close to a power of two.
  151.  
  152. inline static IntRep* Inew(int newlen)
  153. {
  154.   unsigned int siz = sizeof(IntRep) + newlen * sizeof(short) + 
  155.     MALLOC_MIN_OVERHEAD;
  156.   unsigned int allocsiz = MINIntRep_SIZE;
  157.   while (allocsiz < siz) allocsiz <<= 1;  // find a power of 2
  158.   allocsiz -= MALLOC_MIN_OVERHEAD;
  159.   if (allocsiz >= MAXIntRep_SIZE * sizeof(short))
  160.     (*lib_error_handler)("Integer", "Requested length out of range");
  161.     
  162.   IntRep* rep = (IntRep *) new char[allocsiz];
  163.   rep->sz = (allocsiz - sizeof(IntRep) + sizeof(short)) / sizeof(short);
  164.   return rep;
  165. }
  166.  
  167. // allocate: use the bits in src if non-null, clear the rest
  168.  
  169. IntRep* Ialloc(IntRep* old, const unsigned short* src, int srclen, int newsgn,
  170.               int newlen)
  171. {
  172.   IntRep* rep;
  173.   if (old == 0 || newlen > old->sz)
  174.     rep = Inew(newlen);
  175.   else
  176.     rep = old;
  177.  
  178.   rep->len = newlen;
  179.   rep->sgn = newsgn;
  180.  
  181.   scpy(src, rep->s, srclen);
  182.   Iclear_from(rep, srclen);
  183.  
  184.   if (old != rep && old != 0 && !STATIC_IntRep(old)) delete old;
  185.   return rep;
  186. }
  187.  
  188. // allocate and clear
  189.  
  190. IntRep* Icalloc(IntRep* old, int newlen)
  191. {
  192.   IntRep* rep;
  193.   if (old == 0 || newlen > old->sz)
  194.   {
  195.     if (old != 0 && !STATIC_IntRep(old)) delete old;
  196.     rep = Inew(newlen);
  197.   }
  198.   else
  199.     rep = old;
  200.  
  201.   rep->len = newlen;
  202.   rep->sgn = I_POSITIVE;
  203.   Iclear_from(rep, 0);
  204.  
  205.   return rep;
  206. }
  207.  
  208. // reallocate
  209.  
  210. IntRep* Iresize(IntRep* old, int newlen)
  211. {
  212.   IntRep* rep;
  213.   unsigned short oldlen;
  214.   if (old == 0)
  215.   {
  216.     oldlen = 0;
  217.     rep = Inew(newlen);
  218.     rep->sgn = I_POSITIVE;
  219.   }
  220.   else 
  221.   {
  222.     oldlen = old->len;
  223.     if (newlen > old->sz)
  224.     {
  225.       rep = Inew(newlen);
  226.       scpy(old->s, rep->s, oldlen);
  227.       rep->sgn = old->sgn;
  228.       if (!STATIC_IntRep(old)) delete old;
  229.     }
  230.     else
  231.       rep = old;
  232.   }
  233.  
  234.   rep->len = newlen;
  235.   Iclear_from(rep, oldlen);
  236.  
  237.   return rep;
  238. }
  239.  
  240.  
  241. // same, for straight copy
  242.  
  243. IntRep* Icopy(IntRep* old, const IntRep* src)
  244. {
  245.   if (old == src) return old; 
  246.   IntRep* rep;
  247.   if (src == 0)
  248.   {
  249.     if (old == 0)
  250.       rep = Inew(0);
  251.     else
  252.     {
  253.       rep = old;
  254.       Iclear_from(rep, 0);
  255.     }
  256.     rep->len = 0;
  257.     rep->sgn = I_POSITIVE;
  258.   }
  259.   else 
  260.   {
  261.     int newlen = src->len;
  262.     if (old == 0 || newlen > old->sz)
  263.     {
  264.       if (old != 0 && !STATIC_IntRep(old)) delete old;
  265.       rep = Inew(newlen);
  266.     }
  267.     else
  268.       rep = old;
  269.  
  270.     rep->len = newlen;
  271.     rep->sgn = src->sgn;
  272.  
  273.     scpy(src->s, rep->s, newlen);
  274.   }
  275.  
  276.   return rep;
  277. }
  278.  
  279. // allocate & copy space for a long
  280.  
  281. IntRep* Icopy_long(IntRep* old, long x)
  282. {
  283.   unsigned short src[SHORT_PER_LONG];
  284.   unsigned long u;
  285.   int newsgn;
  286.   if (newsgn = (x >= 0))
  287.     u = x;
  288.   else
  289.     u = -x;
  290.   
  291.   unsigned short srclen = 0;
  292.   while (u != 0)
  293.   {
  294.     src[srclen++] = extract(u);
  295.     u = down(u);
  296.   }
  297.  
  298.   IntRep* rep;
  299.   if (old == 0 || srclen > old->sz)
  300.   {
  301.     if (old != 0 && !STATIC_IntRep(old)) delete old;
  302.     rep = Inew(srclen);
  303.   }
  304.   else
  305.     rep = old;
  306.  
  307.   rep->len = srclen;
  308.   rep->sgn = newsgn;
  309.  
  310.   scpy(src, rep->s, srclen);
  311.  
  312.   return rep;
  313.  
  314. }
  315.  
  316. // special case for zero -- it's worth it!
  317.  
  318. IntRep* Icopy_zero(IntRep* old)
  319. {
  320.   if (old == 0)
  321.     return &_ZeroRep;
  322.  
  323.   old->len = 0;
  324.   old->sgn = I_POSITIVE;
  325.  
  326.   return old;
  327. }
  328.  
  329. // special case for 1 or -1
  330.  
  331. IntRep* Icopy_one(IntRep* old, int newsgn)
  332. {
  333.   if (old == 0 || 1 > old->sz)
  334.   {
  335.     if (old != 0 && !STATIC_IntRep(old)) delete old;
  336.     return newsgn==I_NEGATIVE ? &_MinusOneRep : &_OneRep;
  337.   }
  338.  
  339.   old->sgn = newsgn;
  340.   old->len = 1;
  341.   old->s[0] = 1;
  342.  
  343.   return old;
  344. }
  345.  
  346. // convert to a legal two's complement long if possible
  347. // if too big, return most negative/positive value
  348.  
  349. long Itolong(const IntRep* rep)
  350.   if ((unsigned)(rep->len) > (unsigned)(SHORT_PER_LONG))
  351.     return (rep->sgn == I_POSITIVE) ? LONG_MAX : LONG_MIN;
  352.   else if (rep->len == 0)
  353.     return 0;
  354.   else if ((unsigned)(rep->len) < (unsigned)(SHORT_PER_LONG))
  355.   {
  356.     unsigned long a = rep->s[rep->len-1];
  357.     if (SHORT_PER_LONG > 2) // normally optimized out
  358.     {
  359.       for (int i = rep->len - 2; i >= 0; --i)
  360.         a = up(a) | rep->s[i];
  361.     }
  362.     return (rep->sgn == I_POSITIVE)? a : -((long)a);
  363.   }
  364.   else 
  365.   {
  366.     unsigned long a = rep->s[SHORT_PER_LONG - 1];
  367.     if (a >= I_MINNUM)
  368.       return (rep->sgn == I_POSITIVE) ? LONG_MAX : LONG_MIN;
  369.     else
  370.     {
  371.       a = up(a) | rep->s[SHORT_PER_LONG - 2];
  372.       if (SHORT_PER_LONG > 2)
  373.       {
  374.         for (int i = SHORT_PER_LONG - 3; i >= 0; --i)
  375.           a = up(a) | rep->s[i];
  376.       }
  377.       return (rep->sgn == I_POSITIVE)? a : -((long)a);
  378.     }
  379.   }
  380. }
  381.  
  382. // test whether op long() will work.
  383. // careful about asymmetry between LONG_MIN & LONG_MAX
  384.  
  385. int Iislong(const IntRep* rep)
  386. {
  387.   unsigned int l = rep->len;
  388.   if (l < SHORT_PER_LONG)
  389.     return 1;
  390.   else if (l > SHORT_PER_LONG)
  391.     return 0;
  392.   else if ((unsigned)(rep->s[SHORT_PER_LONG - 1]) < (unsigned)(I_MINNUM))
  393.     return 1;
  394.   else if (rep->sgn == I_NEGATIVE && rep->s[SHORT_PER_LONG - 1] == I_MINNUM)
  395.   {
  396.     for (unsigned int i = 0; i < SHORT_PER_LONG - 1; ++i)
  397.       if (rep->s[i] != 0)
  398.         return 0;
  399.     return 1;
  400.   }
  401.   else
  402.     return 0;
  403. }
  404.  
  405. // convert to a double 
  406.  
  407. double Itodouble(const IntRep* rep)
  408.   double d = 0.0;
  409.   double bound = HUGE / 2.0;
  410.   for (int i = rep->len - 1; i >= 0; --i)
  411.   {
  412.     unsigned short a = I_RADIX >> 1;
  413.     while (a != 0)
  414.     {
  415.       if (d >= bound)
  416.         return (rep->sgn == I_NEGATIVE) ? -HUGE : HUGE;
  417.       d *= 2.0;
  418.       if (rep->s[i] & a)
  419.         d += 1.0;
  420.       a >>= 1;
  421.     }
  422.   }
  423.   if (rep->sgn == I_NEGATIVE)
  424.     return -d;
  425.   else
  426.     return d;
  427. }
  428.  
  429. // see whether op double() will work-
  430. // have to actually try it in order to find out
  431. // since otherwise might trigger fp exception
  432.  
  433. int Iisdouble(const IntRep* rep)
  434. {
  435.   double d = 0.0;
  436.   double bound = HUGE / 2.0;
  437.   for (int i = rep->len - 1; i >= 0; --i)
  438.   {
  439.     unsigned short a = I_RADIX >> 1;
  440.     while (a != 0)
  441.     {
  442.       if (d > bound || (d == bound && (i > 0 || (rep->s[i] & a))))
  443.         return 0;
  444.       d *= 2.0;
  445.       if (rep->s[i] & a)
  446.         d += 1.0;
  447.       a >>= 1;
  448.     }
  449.   }
  450.   return 1;
  451. }
  452.  
  453. // real division of num / den
  454.  
  455. double ratio(const Integer& num, const Integer& den)
  456. {
  457.   Integer q, r;
  458.   divide(num, den, q, r);
  459.   double d1 = double(q);
  460.  
  461.   if (d1 == HUGE || d1 == -HUGE || sign(r) == 0)
  462.     return d1;
  463.   else      // use as much precision as available for fractional part
  464.   {
  465.     double  d2 = 0.0;
  466.     double  d3 = 0.0; 
  467.     int cont = 1;
  468.     for (int i = den.rep->len - 1; i >= 0 && cont; --i)
  469.     {
  470.       unsigned short a = I_RADIX >> 1;
  471.       while (a != 0)
  472.       {
  473.         if (d2 + 1.0 == d2) // out of precision when we get here
  474.         {
  475.           cont = 0;
  476.           break;
  477.         }
  478.  
  479.         d2 *= 2.0;
  480.         if (den.rep->s[i] & a)
  481.           d2 += 1.0;
  482.  
  483.         if (i < r.rep->len)
  484.         {
  485.           d3 *= 2.0;
  486.           if (r.rep->s[i] & a)
  487.             d3 += 1.0;
  488.         }
  489.  
  490.         a >>= 1;
  491.       }
  492.     }
  493.  
  494.     if (sign(r) < 0)
  495.       d3 = -d3;
  496.     return d1 + d3 / d2;
  497.   }
  498. }
  499.  
  500. // comparison functions
  501.   
  502. int compare(const IntRep* x, const IntRep* y)
  503. {
  504.   int diff  = x->sgn - y->sgn;
  505.   if (diff == 0)
  506.   {
  507.     diff = x->len - y->len;
  508.     if (diff == 0)
  509.       diff = docmp(x->s, y->s, x->len);
  510.     if (x->sgn == I_NEGATIVE)
  511.       diff = -diff;
  512.   }
  513.   return diff;
  514. }
  515.  
  516. int ucompare(const IntRep* x, const IntRep* y)
  517. {
  518.   int diff = x->len - y->len;
  519.   if (diff == 0)
  520.   {
  521.     int l = x->len;
  522.     const unsigned short* xs = &(x->s[l]);
  523.     const unsigned short* ys = &(y->s[l]);
  524.     while (l-- > 0 && (diff = (*--xs) - (*--ys)) == 0);
  525.   }
  526.   return diff;
  527. }
  528.  
  529. int compare(const IntRep* x, long  y)
  530. {
  531.   int xl = x->len;
  532.   int xsgn = x->sgn;
  533.   if (y == 0)
  534.   {
  535.     if (xl == 0)
  536.       return 0;
  537.     else if (xsgn == I_NEGATIVE)
  538.       return -1;
  539.     else
  540.       return 1;
  541.   }
  542.   else
  543.   {
  544.     int ysgn = y >= 0;
  545.     unsigned long uy = (ysgn)? y : -y;
  546.     int diff = xsgn - ysgn;
  547.     if (diff == 0)
  548.     {
  549.       diff = xl - SHORT_PER_LONG;
  550.       if (diff <= 0)
  551.       {
  552.         unsigned short tmp[SHORT_PER_LONG];
  553.         int yl = 0;
  554.         while (uy != 0)
  555.         {
  556.           tmp[yl++] = extract(uy);
  557.           uy = down(uy);
  558.         }
  559.         diff = xl - yl;
  560.         if (diff == 0)
  561.           diff = docmp(x->s, tmp, xl);
  562.       }
  563.     }
  564.     if (xsgn == I_NEGATIVE)
  565.       diff = -diff;
  566.     return diff;
  567.   }
  568. }
  569.  
  570. int ucompare(const IntRep* x, long  y)
  571. {
  572.   int xl = x->len;
  573.   if (y == 0)
  574.     return xl;
  575.   else
  576.   {
  577.     unsigned long uy = (y >= 0)? y : -y;
  578.     int diff = xl - SHORT_PER_LONG;
  579.     if (diff <= 0)
  580.     {
  581.       unsigned short tmp[SHORT_PER_LONG];
  582.       int yl = 0;
  583.       while (uy != 0)
  584.       {
  585.         tmp[yl++] = extract(uy);
  586.         uy = down(uy);
  587.       }
  588.       diff = xl - yl;
  589.       if (diff == 0)
  590.         diff = docmp(x->s, tmp, xl);
  591.     }
  592.     return diff;
  593.   }
  594. }
  595.  
  596.  
  597.  
  598. // arithmetic functions
  599.  
  600. IntRep* add(const IntRep* x, int negatex, 
  601.             const IntRep* y, int negatey, IntRep* r)
  602. {
  603.   nonnil(x);
  604.   nonnil(y);
  605.  
  606.   int xl = x->len;
  607.   int yl = y->len;
  608.  
  609.   int xsgn = (negatex && xl != 0) ? !x->sgn : x->sgn;
  610.   int ysgn = (negatey && yl != 0) ? !y->sgn : y->sgn;
  611.  
  612.   int xrsame = x == r;
  613.   int yrsame = y == r;
  614.  
  615.   if (yl == 0)
  616.     r = Ialloc(r, x->s, xl, xsgn, xl);
  617.   else if (xl == 0)
  618.     r = Ialloc(r, y->s, yl, ysgn, yl);
  619.   else if (xsgn == ysgn)
  620.   {
  621.     if (xrsame || yrsame)
  622.       r = Iresize(r, calc_len(xl, yl, 1));
  623.     else
  624.       r = Icalloc(r, calc_len(xl, yl, 1));
  625.     r->sgn = xsgn;
  626.     unsigned short* rs = r->s;
  627.     const unsigned short* as;
  628.     const unsigned short* bs;
  629.     const unsigned short* topa;
  630.     const unsigned short* topb;
  631.     if (xl >= yl)
  632.     {
  633.       as =  (xrsame)? r->s : x->s;
  634.       topa = &(as[xl]);
  635.       bs =  (yrsame)? r->s : y->s;
  636.       topb = &(bs[yl]);
  637.     }
  638.     else
  639.     {
  640.       bs =  (xrsame)? r->s : x->s;
  641.       topb = &(bs[xl]);
  642.       as =  (yrsame)? r->s : y->s;
  643.       topa = &(as[yl]);
  644.     }
  645.     unsigned long sum = 0;
  646.     while (bs < topb)
  647.     {
  648.       sum += (unsigned long)(*as++) + (unsigned long)(*bs++);
  649.       *rs++ = extract(sum);
  650.       sum = down(sum);
  651.     }
  652.     while (sum != 0 && as < topa)
  653.     {
  654.       sum += (unsigned long)(*as++);
  655.       *rs++ = extract(sum);
  656.       sum = down(sum);
  657.     }
  658.     if (sum != 0)
  659.       *rs = extract(sum);
  660.     else if (rs != as)
  661.       while (as < topa)
  662.         *rs++ = *as++;
  663.   }
  664.   else
  665.   {
  666.     int comp = ucompare(x, y);
  667.     if (comp == 0)
  668.       r = Icopy_zero(r);
  669.     else
  670.     {
  671.       if (xrsame || yrsame)
  672.         r = Iresize(r, calc_len(xl, yl, 0));
  673.       else
  674.         r = Icalloc(r, calc_len(xl, yl, 0));
  675.       unsigned short* rs = r->s;
  676.       const unsigned short* as;
  677.       const unsigned short* bs;
  678.       const unsigned short* topa;
  679.       const unsigned short* topb;
  680.       if (comp > 0)
  681.       {
  682.         as =  (xrsame)? r->s : x->s;
  683.         topa = &(as[xl]);
  684.         bs =  (yrsame)? r->s : y->s;
  685.         topb = &(bs[yl]);
  686.         r->sgn = xsgn;
  687.       }
  688.       else
  689.       {
  690.         bs =  (xrsame)? r->s : x->s;
  691.         topb = &(bs[xl]);
  692.         as =  (yrsame)? r->s : y->s;
  693.         topa = &(as[yl]);
  694.         r->sgn = ysgn;
  695.       }
  696.       unsigned long hi = 1;
  697.       while (bs < topb)
  698.       {
  699.         hi += (unsigned long)(*as++) + I_MAXNUM - (unsigned long)(*bs++);
  700.         *rs++ = extract(hi);
  701.         hi = down(hi);
  702.       }
  703.       while (hi == 0 && as < topa)
  704.       {
  705.         hi = (unsigned long)(*as++) + I_MAXNUM;
  706.         *rs++ = extract(hi);
  707.         hi = down(hi);
  708.       }
  709.       if (rs != as)
  710.         while (as < topa)
  711.           *rs++ = *as++;
  712.     }
  713.   }
  714.   Icheck(r);
  715.   return r;
  716. }
  717.  
  718.  
  719. IntRep* add(const IntRep* x, int negatex, long y, IntRep* r)
  720. {
  721.   nonnil(x);
  722.   int xl = x->len;
  723.   int xsgn = (negatex && xl != 0) ? !x->sgn : x->sgn;
  724.   int xrsame = x == r;
  725.  
  726.   int ysgn = (y >= 0);
  727.   unsigned long uy = (ysgn)? y : -y;
  728.  
  729.   if (y == 0)
  730.     r = Ialloc(r, x->s, xl, xsgn, xl);
  731.   else if (xl == 0)
  732.     r = Icopy_long(r, y);
  733.   else if (xsgn == ysgn)
  734.   {
  735.     if (xrsame)
  736.       r = Iresize(r, calc_len(xl, SHORT_PER_LONG, 1));
  737.     else
  738.       r = Icalloc(r, calc_len(xl, SHORT_PER_LONG, 1));
  739.     r->sgn = xsgn;
  740.     unsigned short* rs = r->s;
  741.     const unsigned short* as =  (xrsame)? r->s : x->s;
  742.     const unsigned short* topa = &(as[xl]);
  743.     unsigned long sum = 0;
  744.     while (as < topa && uy != 0)
  745.     {
  746.       unsigned long u = extract(uy);
  747.       uy = down(uy);
  748.       sum += (unsigned long)(*as++) + u;
  749.       *rs++ = extract(sum);
  750.       sum = down(sum);
  751.     }
  752.     while (sum != 0 && as < topa)
  753.     {
  754.       sum += (unsigned long)(*as++);
  755.       *rs++ = extract(sum);
  756.       sum = down(sum);
  757.     }
  758.     if (sum != 0)
  759.       *rs = extract(sum);
  760.     else if (rs != as)
  761.       while (as < topa)
  762.         *rs++ = *as++;
  763.   }
  764.   else
  765.   {
  766.     unsigned short tmp[SHORT_PER_LONG];
  767.     int yl = 0;
  768.     while (uy != 0)
  769.     {
  770.       tmp[yl++] = extract(uy);
  771.       uy = down(uy);
  772.     }
  773.     int comp = xl - yl;
  774.     if (comp == 0)
  775.       comp = docmp(x->s, tmp, yl);
  776.     if (comp == 0)
  777.       r = Icopy_zero(r);
  778.     else
  779.     {
  780.       if (xrsame)
  781.         r = Iresize(r, calc_len(xl, yl, 0));
  782.       else
  783.         r = Icalloc(r, calc_len(xl, yl, 0));
  784.       unsigned short* rs = r->s;
  785.       const unsigned short* as;
  786.       const unsigned short* bs;
  787.       const unsigned short* topa;
  788.       const unsigned short* topb;
  789.       if (comp > 0)
  790.       {
  791.         as =  (xrsame)? r->s : x->s;
  792.         topa = &(as[xl]);
  793.         bs =  tmp;
  794.         topb = &(bs[yl]);
  795.         r->sgn = xsgn;
  796.       }
  797.       else
  798.       {
  799.         bs =  (xrsame)? r->s : x->s;
  800.         topb = &(bs[xl]);
  801.         as =  tmp;
  802.         topa = &(as[yl]);
  803.         r->sgn = ysgn;
  804.       }
  805.       unsigned long hi = 1;
  806.       while (bs < topb)
  807.       {
  808.         hi += (unsigned long)(*as++) + I_MAXNUM - (unsigned long)(*bs++);
  809.         *rs++ = extract(hi);
  810.         hi = down(hi);
  811.       }
  812.       while (hi == 0 && as < topa)
  813.       {
  814.         hi = (unsigned long)(*as++) + I_MAXNUM;
  815.         *rs++ = extract(hi);
  816.         hi = down(hi);
  817.       }
  818.       if (rs != as)
  819.         while (as < topa)
  820.           *rs++ = *as++;
  821.     }
  822.   }
  823.   Icheck(r);
  824.   return r;
  825. }
  826.  
  827.  
  828. IntRep* multiply(const IntRep* x, const IntRep* y, IntRep* r)
  829. {
  830.   nonnil(x);
  831.   nonnil(y);
  832.   int xl = x->len;
  833.   int yl = y->len;
  834.   int rl = xl + yl;
  835.   int rsgn = x->sgn == y->sgn;
  836.   int xrsame = x == r;
  837.   int yrsame = y == r;
  838.   int xysame = x == y;
  839.   
  840.   if (xl == 0 || yl == 0)
  841.     r = Icopy_zero(r);
  842.   else if (xl == 1 && x->s[0] == 1)
  843.     r = Icopy(r, y);
  844.   else if (yl == 1 && y->s[0] == 1)
  845.     r = Icopy(r, x);
  846.   else if (!(xysame && xrsame))
  847.   {
  848.     if (xrsame || yrsame)
  849.       r = Iresize(r, rl);
  850.     else
  851.       r = Icalloc(r, rl);
  852.     unsigned short* rs = r->s;
  853.     unsigned short* topr = &(rs[rl]);
  854.  
  855.     // use best inner/outer loop params given constraints
  856.     unsigned short* currentr;
  857.     const unsigned short* bota;
  858.     const unsigned short* as;
  859.     const unsigned short* botb;
  860.     const unsigned short* topb;
  861.     if (xrsame)                 
  862.     { 
  863.       currentr = &(rs[xl-1]);
  864.       bota = rs;
  865.       as = currentr;
  866.       botb = y->s;
  867.       topb = &(botb[yl]);
  868.     }
  869.     else if (yrsame)
  870.     {
  871.       currentr = &(rs[yl-1]);
  872.       bota = rs;
  873.       as = currentr;
  874.       botb = x->s;
  875.       topb = &(botb[xl]);
  876.     }
  877.     else if (xl <= yl)
  878.     {
  879.       currentr = &(rs[xl-1]);
  880.       bota = x->s;
  881.       as = &(bota[xl-1]);
  882.       botb = y->s;
  883.       topb = &(botb[yl]);
  884.     }
  885.     else
  886.     {
  887.       currentr = &(rs[yl-1]);
  888.       bota = y->s;
  889.       as = &(bota[yl-1]);
  890.       botb = x->s;
  891.       topb = &(botb[xl]);
  892.     }
  893.  
  894.     while (as >= bota)
  895.     {
  896.       unsigned long ai = (unsigned long)(*as--);
  897.       unsigned short* rs = currentr--;
  898.       *rs = 0;
  899.       if (ai != 0)
  900.       {
  901.         unsigned long sum = 0;
  902.         const unsigned short* bs = botb;
  903.         while (bs < topb)
  904.         {
  905.           sum += ai * (unsigned long)(*bs++) + (unsigned long)(*rs);
  906.           *rs++ = extract(sum);
  907.           sum = down(sum);
  908.         }
  909.         while (sum != 0 && rs < topr)
  910.         {
  911.           sum += (unsigned long)(*rs);
  912.           *rs++ = extract(sum);
  913.           sum = down(sum);
  914.         }
  915.       }
  916.     }
  917.   }
  918.   else                          // x, y, and r same; compute over diagonals
  919.   {
  920.     r = Iresize(r, rl);
  921.     unsigned short* botr = r->s;
  922.     unsigned short* topr = &(botr[rl]);
  923.     unsigned short* rs =   &(botr[rl - 2]);
  924.  
  925.     const unsigned short* bota = (xrsame)? botr : x->s;
  926.     const unsigned short* loa =  &(bota[xl - 1]);
  927.     const unsigned short* hia =  loa;
  928.  
  929.     for (; rs >= botr; --rs)
  930.     {
  931.       const unsigned short* h = hia;
  932.       const unsigned short* l = loa;
  933.       unsigned long prod = (unsigned long)(*h) * (unsigned long)(*l);
  934.       *rs = 0;
  935.  
  936.       for(;;)
  937.       {
  938.         unsigned short* rt = rs;
  939.         unsigned long sum = prod + (unsigned long)(*rt);
  940.         *rt++ = extract(sum);
  941.         sum = down(sum);
  942.         while (sum != 0 && rt < topr)
  943.         {
  944.           sum += (unsigned long)(*rt);
  945.           *rt++ = extract(sum);
  946.           sum = down(sum);
  947.         }
  948.         if (h > l)
  949.         {
  950.           rt = rs;
  951.           sum = prod + (unsigned long)(*rt);
  952.           *rt++ = extract(sum);
  953.           sum = down(sum);
  954.           while (sum != 0 && rt < topr)
  955.           {
  956.             sum += (unsigned long)(*rt);
  957.             *rt++ = extract(sum);
  958.             sum = down(sum);
  959.           }
  960.           if (--h >= ++l)
  961.             prod = (unsigned long)(*h) * (unsigned long)(*l);
  962.           else
  963.             break;
  964.         }
  965.         else
  966.           break;
  967.       }
  968.       if (loa > bota)
  969.         --loa;
  970.       else
  971.         --hia;
  972.     }
  973.   }
  974.   r->sgn = rsgn;
  975.   Icheck(r);
  976.   return r;
  977. }
  978.  
  979.  
  980. IntRep* multiply(const IntRep* x, long y, IntRep* r)
  981. {
  982.   nonnil(x);
  983.   int xl = x->len;
  984.     
  985.   if (xl == 0 || y == 0)
  986.     r = Icopy_zero(r);
  987.   else if (y == 1)
  988.     r = Icopy(r, x);
  989.   else
  990.   {
  991.     int ysgn = y >= 0;
  992.     int rsgn = x->sgn == ysgn;
  993.     unsigned long uy = (ysgn)? y : -y;
  994.     unsigned short tmp[SHORT_PER_LONG];
  995.     int yl = 0;
  996.     while (uy != 0)
  997.     {
  998.       tmp[yl++] = extract(uy);
  999.       uy = down(uy);
  1000.     }
  1001.  
  1002.     int rl = xl + yl;
  1003.     int xrsame = x == r;
  1004.     if (xrsame)
  1005.       r = Iresize(r, rl);
  1006.     else
  1007.       r = Icalloc(r, rl);
  1008.  
  1009.     unsigned short* rs = r->s;
  1010.     unsigned short* topr = &(rs[rl]);
  1011.     unsigned short* currentr;
  1012.     const unsigned short* bota;
  1013.     const unsigned short* as;
  1014.     const unsigned short* botb;
  1015.     const unsigned short* topb;
  1016.  
  1017.     if (xrsame)
  1018.     { 
  1019.       currentr = &(rs[xl-1]);
  1020.       bota = rs;
  1021.       as = currentr;
  1022.       botb = tmp;
  1023.       topb = &(botb[yl]);
  1024.     }
  1025.     else if (xl <= yl)
  1026.     {
  1027.       currentr = &(rs[xl-1]);
  1028.       bota = x->s;
  1029.       as = &(bota[xl-1]);
  1030.       botb = tmp;
  1031.       topb = &(botb[yl]);
  1032.     }
  1033.     else
  1034.     {
  1035.       currentr = &(rs[yl-1]);
  1036.       bota = tmp;
  1037.       as = &(bota[yl-1]);
  1038.       botb = x->s;
  1039.       topb = &(botb[xl]);
  1040.     }
  1041.  
  1042.     while (as >= bota)
  1043.     {
  1044.       unsigned long ai = (unsigned long)(*as--);
  1045.       unsigned short* rs = currentr--;
  1046.       *rs = 0;
  1047.       if (ai != 0)
  1048.       {
  1049.         unsigned long sum = 0;
  1050.         const unsigned short* bs = botb;
  1051.         while (bs < topb)
  1052.         {
  1053.           sum += ai * (unsigned long)(*bs++) + (unsigned long)(*rs);
  1054.           *rs++ = extract(sum);
  1055.           sum = down(sum);
  1056.         }
  1057.         while (sum != 0 && rs < topr)
  1058.         {
  1059.           sum += (unsigned long)(*rs);
  1060.           *rs++ = extract(sum);
  1061.           sum = down(sum);
  1062.         }
  1063.       }
  1064.     }
  1065.     r->sgn = rsgn;
  1066.   }
  1067.   Icheck(r);
  1068.   return r;
  1069. }
  1070.  
  1071.  
  1072. // main division routine
  1073.  
  1074. static void do_divide(unsigned short* rs,
  1075.                       const unsigned short* ys, int yl,
  1076.                       unsigned short* qs, int ql)
  1077. {
  1078.   const unsigned short* topy = &(ys[yl]);
  1079.   unsigned short d1 = ys[yl - 1];
  1080.   unsigned short d2 = ys[yl - 2];
  1081.  
  1082.   int l = ql - 1;
  1083.   int i = l + yl;
  1084.   
  1085.   for (; l >= 0; --l, --i)
  1086.   {
  1087.     unsigned short qhat;       // guess q
  1088.     if (d1 == rs[i])
  1089.       qhat = I_MAXNUM;
  1090.     else
  1091.     {
  1092.       unsigned long lr = up((unsigned long)rs[i]) | rs[i-1];
  1093.       qhat = lr / d1;
  1094.     }
  1095.  
  1096.     for(;;)     // adjust q, use docmp to avoid overflow problems
  1097.     {
  1098.       unsigned short ts[3];
  1099.       unsigned long prod = (unsigned long)d2 * (unsigned long)qhat;
  1100.       ts[0] = extract(prod);
  1101.       prod = down(prod) + (unsigned long)d1 * (unsigned long)qhat;
  1102.       ts[1] = extract(prod);
  1103.       ts[2] = extract(down(prod));
  1104.       if (docmp(ts, &(rs[i-2]), 3) > 0)
  1105.         --qhat;
  1106.       else
  1107.         break;
  1108.     };
  1109.     
  1110.     // multiply & subtract
  1111.     
  1112.     const unsigned short* yt = ys;
  1113.     unsigned short* rt = &(rs[l]);
  1114.     unsigned long prod = 0;
  1115.     unsigned long hi = 1;
  1116.     while (yt < topy)
  1117.     {
  1118.       prod = (unsigned long)qhat * (unsigned long)(*yt++) + down(prod);
  1119.       hi += (unsigned long)(*rt) + I_MAXNUM - (unsigned long)(extract(prod));
  1120.       *rt++ = extract(hi);
  1121.       hi = down(hi);
  1122.     }
  1123.     hi += (unsigned long)(*rt) + I_MAXNUM - (unsigned long)(down(prod));
  1124.     *rt = extract(hi);
  1125.     hi = down(hi);
  1126.     
  1127.     // off-by-one, add back
  1128.     
  1129.     if (hi == 0)
  1130.     {
  1131.       --qhat;
  1132.       yt = ys;
  1133.       rt = &(rs[l]);
  1134.       hi = 0;
  1135.       while (yt < topy)
  1136.       {
  1137.         hi = (unsigned long)(*rt) + (unsigned long)(*yt++) + down(hi);
  1138.         *rt++ = extract(hi);
  1139.       }
  1140.       *rt = 0;
  1141.     }
  1142.     if (qs != 0)
  1143.       qs[l] = qhat;
  1144.   }
  1145. }
  1146.  
  1147. // divide by single digit, return remainder
  1148. // if q != 0, then keep the result in q, else just compute rem
  1149.  
  1150. static int unscale(const unsigned short* x, int xl, unsigned short y,
  1151.                    unsigned short* q)
  1152. {
  1153.   if (xl == 0 || y == 1)
  1154.     return 0;
  1155.   else if (q != 0)
  1156.   {
  1157.     unsigned short* botq = q;
  1158.     unsigned short* qs = &(botq[xl - 1]);
  1159.     const unsigned short* xs = &(x[xl - 1]);
  1160.     unsigned long rem = 0;
  1161.     while (qs >= botq)
  1162.     {
  1163.       rem = up(rem) | *xs--;
  1164.       unsigned long u = rem / y;
  1165.       *qs-- = extract(u);
  1166.       rem -= u * y;
  1167.     }
  1168.     int r = extract(rem);
  1169.     return r;
  1170.   }
  1171.   else                          // same loop, a bit faster if just need rem
  1172.   {
  1173.     const unsigned short* botx = x;
  1174.     const unsigned short* xs = &(botx[xl - 1]);
  1175.     unsigned long rem = 0;
  1176.     while (xs >= botx)
  1177.     {
  1178.       rem = up(rem) | *xs--;
  1179.       unsigned long u = rem / y;
  1180.       rem -= u * y;
  1181.     }
  1182.     int r = extract(rem);
  1183.     return r;
  1184.   }
  1185. }
  1186.  
  1187.  
  1188. IntRep* div(const IntRep* x, const IntRep* y, IntRep* q)
  1189. {
  1190.   nonnil(x);
  1191.   nonnil(y);
  1192.   int xl = x->len;
  1193.   int yl = y->len;
  1194.   if (yl == 0) (*lib_error_handler)("Integer", "attempted division by zero");
  1195.  
  1196.   int comp = ucompare(x, y);
  1197.   int xsgn = x->sgn;
  1198.   int ysgn = y->sgn;
  1199.  
  1200.   int samesign = xsgn == ysgn;
  1201.  
  1202.   if (comp < 0)
  1203.     q = Icopy_zero(q);
  1204.   else if (comp == 0)
  1205.     q = Icopy_one(q, samesign);
  1206.   else if (yl == 1)
  1207.   {
  1208.     q = Icopy(q, x);
  1209.     unscale(q->s, q->len, y->s[0], q->s);
  1210.   }
  1211.   else
  1212.   {
  1213.     IntRep* yy = 0;
  1214.     IntRep* r  = 0;
  1215.     unsigned short prescale = (I_RADIX / (1 + y->s[yl - 1]));
  1216.     if (prescale != 1 || y == q)
  1217.     {
  1218.       yy = multiply(y, ((long)prescale & I_MAXNUM), yy);
  1219.       r = multiply(x, ((long)prescale & I_MAXNUM), r);
  1220.     }
  1221.     else
  1222.     {
  1223.       yy = (IntRep*)y;
  1224.       r = Icalloc(r, xl + 1);
  1225.       scpy(x->s, r->s, xl);
  1226.     }
  1227.  
  1228.     int ql = xl - yl + 1;
  1229.       
  1230.     q = Icalloc(q, ql);
  1231.     do_divide(r->s, yy->s, yl, q->s, ql);
  1232.  
  1233.     if (yy != y && !STATIC_IntRep(yy)) delete yy;
  1234.     if (!STATIC_IntRep(r)) delete r;
  1235.   }
  1236.   q->sgn = samesign;
  1237.   Icheck(q);
  1238.   return q;
  1239. }
  1240.  
  1241. IntRep* div(const IntRep* x, long y, IntRep* q)
  1242. {
  1243.   nonnil(x);
  1244.   int xl = x->len;
  1245.   if (y == 0) (*lib_error_handler)("Integer", "attempted division by zero");
  1246.  
  1247.   unsigned short ys[SHORT_PER_LONG];
  1248.   unsigned long u;
  1249.   int ysgn = y >= 0;
  1250.   if (ysgn)
  1251.     u = y;
  1252.   else
  1253.     u = -y;
  1254.   int yl = 0;
  1255.   while (u != 0)
  1256.   {
  1257.     ys[yl++] = extract(u);
  1258.     u = down(u);
  1259.   }
  1260.  
  1261.   int comp = xl - yl;
  1262.   if (comp == 0) comp = docmp(x->s, ys, xl);
  1263.  
  1264.   int xsgn = x->sgn;
  1265.   int samesign = xsgn == ysgn;
  1266.  
  1267.   if (comp < 0)
  1268.     q = Icopy_zero(q);
  1269.   else if (comp == 0)
  1270.   {
  1271.     q = Icopy_one(q, samesign);
  1272.   }
  1273.   else if (yl == 1)
  1274.   {
  1275.     q = Icopy(q, x);
  1276.     unscale(q->s, q->len, ys[0], q->s);
  1277.   }
  1278.   else
  1279.   {
  1280.     IntRep* r  = 0;
  1281.     unsigned short prescale = (I_RADIX / (1 + ys[yl - 1]));
  1282.     if (prescale != 1)
  1283.     {
  1284.       unsigned long prod = (unsigned long)prescale * (unsigned long)ys[0];
  1285.       ys[0] = extract(prod);
  1286.       prod = down(prod) + (unsigned long)prescale * (unsigned long)ys[1];
  1287.       ys[1] = extract(prod);
  1288.       r = multiply(x, ((long)prescale & I_MAXNUM), r);
  1289.     }
  1290.     else
  1291.     {
  1292.       r = Icalloc(r, xl + 1);
  1293.       scpy(x->s, r->s, xl);
  1294.     }
  1295.  
  1296.     int ql = xl - yl + 1;
  1297.       
  1298.     q = Icalloc(q, ql);
  1299.     do_divide(r->s, ys, yl, q->s, ql);
  1300.  
  1301.     if (!STATIC_IntRep(r)) delete r;
  1302.   }
  1303.   q->sgn = samesign;
  1304.   Icheck(q);
  1305.   return q;
  1306. }
  1307.  
  1308.  
  1309. void divide(const Integer& Ix, long y, Integer& Iq, long& rem)
  1310. {
  1311.   const IntRep* x = Ix.rep;
  1312.   nonnil(x);
  1313.   IntRep* q = Iq.rep;
  1314.   int xl = x->len;
  1315.   if (y == 0) (*lib_error_handler)("Integer", "attempted division by zero");
  1316.  
  1317.   unsigned short ys[SHORT_PER_LONG];
  1318.   unsigned long u;
  1319.   int ysgn = y >= 0;
  1320.   if (ysgn)
  1321.     u = y;
  1322.   else
  1323.     u = -y;
  1324.   int yl = 0;
  1325.   while (u != 0)
  1326.   {
  1327.     ys[yl++] = extract(u);
  1328.     u = down(u);
  1329.   }
  1330.  
  1331.   int comp = xl - yl;
  1332.   if (comp == 0) comp = docmp(x->s, ys, xl);
  1333.  
  1334.   int xsgn = x->sgn;
  1335.   int samesign = xsgn == ysgn;
  1336.  
  1337.   if (comp < 0)
  1338.   {
  1339.     rem = Itolong(x);
  1340.     q = Icopy_zero(q);
  1341.   }
  1342.   else if (comp == 0)
  1343.   {
  1344.     q = Icopy_one(q, samesign);
  1345.     rem = 0;
  1346.   }
  1347.   else if (yl == 1)
  1348.   {
  1349.     q = Icopy(q, x);
  1350.     rem = unscale(q->s, q->len, ys[0], q->s);
  1351.   }
  1352.   else
  1353.   {
  1354.     IntRep* r  = 0;
  1355.     unsigned short prescale = (I_RADIX / (1 + ys[yl - 1]));
  1356.     if (prescale != 1)
  1357.     {
  1358.       unsigned long prod = (unsigned long)prescale * (unsigned long)ys[0];
  1359.       ys[0] = extract(prod);
  1360.       prod = down(prod) + (unsigned long)prescale * (unsigned long)ys[1];
  1361.       ys[1] = extract(prod);
  1362.       r = multiply(x, ((long)prescale & I_MAXNUM), r);
  1363.     }
  1364.     else
  1365.     {
  1366.       r = Icalloc(r, xl + 1);
  1367.       scpy(x->s, r->s, xl);
  1368.     }
  1369.  
  1370.     int ql = xl - yl + 1;
  1371.       
  1372.     q = Icalloc(q, ql);
  1373.     
  1374.     do_divide(r->s, ys, yl, q->s, ql);
  1375.  
  1376.     if (prescale != 1)
  1377.     {
  1378.       Icheck(r);
  1379.       unscale(r->s, r->len, prescale, r->s);
  1380.     }
  1381.     Icheck(r);
  1382.     rem = Itolong(r);
  1383.     if (!STATIC_IntRep(r)) delete r;
  1384.   }
  1385.   rem = abs(rem);
  1386.   if (xsgn == I_NEGATIVE) rem = -rem;
  1387.   q->sgn = samesign;
  1388.   Icheck(q);
  1389.   Iq.rep = q;
  1390. }
  1391.  
  1392.  
  1393. void divide(const Integer& Ix, const Integer& Iy, Integer& Iq, Integer& Ir)
  1394. {
  1395.   const IntRep* x = Ix.rep;
  1396.   nonnil(x);
  1397.   const IntRep* y = Iy.rep;
  1398.   nonnil(y);
  1399.   IntRep* q = Iq.rep;
  1400.   IntRep* r = Ir.rep;
  1401.  
  1402.   int xl = x->len;
  1403.   int yl = y->len;
  1404.   if (yl == 0)
  1405.     (*lib_error_handler)("Integer", "attempted division by zero");
  1406.  
  1407.   int comp = ucompare(x, y);
  1408.   int xsgn = x->sgn;
  1409.   int ysgn = y->sgn;
  1410.  
  1411.   int samesign = xsgn == ysgn;
  1412.  
  1413.   if (comp < 0)
  1414.   {
  1415.     q = Icopy_zero(q);
  1416.     r = Icopy(r, x);
  1417.   }
  1418.   else if (comp == 0)
  1419.   {
  1420.     q = Icopy_one(q, samesign);
  1421.     r = Icopy_zero(r);
  1422.   }
  1423.   else if (yl == 1)
  1424.   {
  1425.     q = Icopy(q, x);
  1426.     int rem =  unscale(q->s, q->len, y->s[0], q->s);
  1427.     r = Icopy_long(r, rem);
  1428.     if (rem != 0)
  1429.       r->sgn = xsgn;
  1430.   }
  1431.   else
  1432.   {
  1433.     IntRep* yy = 0;
  1434.     unsigned short prescale = (I_RADIX / (1 + y->s[yl - 1]));
  1435.     if (prescale != 1 || y == q || y == r)
  1436.     {
  1437.       yy = multiply(y, ((long)prescale & I_MAXNUM), yy);
  1438.       r = multiply(x, ((long)prescale & I_MAXNUM), r);
  1439.     }
  1440.     else
  1441.     {
  1442.       yy = (IntRep*)y;
  1443.       r = Icalloc(r, xl + 1);
  1444.       scpy(x->s, r->s, xl);
  1445.     }
  1446.  
  1447.     int ql = xl - yl + 1;
  1448.       
  1449.     q = Icalloc(q, ql);
  1450.     do_divide(r->s, yy->s, yl, q->s, ql);
  1451.  
  1452.     if (yy != y && !STATIC_IntRep(yy)) delete yy;
  1453.     if (prescale != 1)
  1454.     {
  1455.       Icheck(r);
  1456.       unscale(r->s, r->len, prescale, r->s);
  1457.     }
  1458.   }
  1459.   q->sgn = samesign;
  1460.   Icheck(q);
  1461.   Iq.rep = q;
  1462.   Icheck(r);
  1463.   Ir.rep = r;
  1464. }
  1465.  
  1466. IntRep* mod(const IntRep* x, const IntRep* y, IntRep* r)
  1467. {
  1468.   nonnil(x);
  1469.   nonnil(y);
  1470.   int xl = x->len;
  1471.   int yl = y->len;
  1472.   if (yl == 0) (*lib_error_handler)("Integer", "attempted division by zero");
  1473.  
  1474.   int comp = ucompare(x, y);
  1475.   int xsgn = x->sgn;
  1476.  
  1477.   if (comp < 0)
  1478.     r = Icopy(r, x);
  1479.   else if (comp == 0)
  1480.     r = Icopy_zero(r);
  1481.   else if (yl == 1)
  1482.   {
  1483.     int rem = unscale(x->s, xl, y->s[0], 0);
  1484.     r = Icopy_long(r, rem);
  1485.     if (rem != 0)
  1486.       r->sgn = xsgn;
  1487.   }
  1488.   else
  1489.   {
  1490.     IntRep* yy = 0;
  1491.     unsigned short prescale = (I_RADIX / (1 + y->s[yl - 1]));
  1492.     if (prescale != 1 || y == r)
  1493.     {
  1494.       yy = multiply(y, ((long)prescale & I_MAXNUM), yy);
  1495.       r = multiply(x, ((long)prescale & I_MAXNUM), r);
  1496.     }
  1497.     else
  1498.     {
  1499.       yy = (IntRep*)y;
  1500.       r = Icalloc(r, xl + 1);
  1501.       scpy(x->s, r->s, xl);
  1502.     }
  1503.       
  1504.     do_divide(r->s, yy->s, yl, 0, xl - yl + 1);
  1505.  
  1506.     if (yy != y && !STATIC_IntRep(yy)) delete yy;
  1507.  
  1508.     if (prescale != 1)
  1509.     {
  1510.       Icheck(r);
  1511.       unscale(r->s, r->len, prescale, r->s);
  1512.     }
  1513.   }
  1514.   Icheck(r);
  1515.   return r;
  1516. }
  1517.  
  1518. IntRep* mod(const IntRep* x, long y, IntRep* r)
  1519. {
  1520.   nonnil(x);
  1521.   int xl = x->len;
  1522.   if (y == 0) (*lib_error_handler)("Integer", "attempted division by zero");
  1523.  
  1524.   unsigned short ys[SHORT_PER_LONG];
  1525.   unsigned long u;
  1526.   int ysgn = y >= 0;
  1527.   if (ysgn)
  1528.     u = y;
  1529.   else
  1530.     u = -y;
  1531.   int yl = 0;
  1532.   while (u != 0)
  1533.   {
  1534.     ys[yl++] = extract(u);
  1535.     u = down(u);
  1536.   }
  1537.  
  1538.   int comp = xl - yl;
  1539.   if (comp == 0) comp = docmp(x->s, ys, xl);
  1540.  
  1541.   int xsgn = x->sgn;
  1542.  
  1543.   if (comp < 0)
  1544.     r = Icopy(r, x);
  1545.   else if (comp == 0)
  1546.     r = Icopy_zero(r);
  1547.   else if (yl == 1)
  1548.   {
  1549.     int rem = unscale(x->s, xl, ys[0], 0);
  1550.     r = Icopy_long(r, rem);
  1551.     if (rem != 0)
  1552.       r->sgn = xsgn;
  1553.   }
  1554.   else
  1555.   {
  1556.     unsigned short prescale = (I_RADIX / (1 + ys[yl - 1]));
  1557.     if (prescale != 1)
  1558.     {
  1559.       unsigned long prod = (unsigned long)prescale * (unsigned long)ys[0];
  1560.       ys[0] = extract(prod);
  1561.       prod = down(prod) + (unsigned long)prescale * (unsigned long)ys[1];
  1562.       ys[1] = extract(prod);
  1563.       r = multiply(x, ((long)prescale & I_MAXNUM), r);
  1564.     }
  1565.     else
  1566.     {
  1567.       r = Icalloc(r, xl + 1);
  1568.       scpy(x->s, r->s, xl);
  1569.     }
  1570.       
  1571.     do_divide(r->s, ys, yl, 0, xl - yl + 1);
  1572.  
  1573.     if (prescale != 1)
  1574.     {
  1575.       Icheck(r);
  1576.       unscale(r->s, r->len, prescale, r->s);
  1577.     }
  1578.   }
  1579.   Icheck(r);
  1580.   return r;
  1581. }
  1582.  
  1583. IntRep* lshift(const IntRep* x, long y, IntRep* r)
  1584. {
  1585.   nonnil(x);
  1586.   int xl = x->len;
  1587.   if (xl == 0 || y == 0)
  1588.   {
  1589.     r = Icopy(r, x);
  1590.     return r;
  1591.   }
  1592.  
  1593.   int xrsame = x == r;
  1594.   int rsgn = x->sgn;
  1595.  
  1596.   long ay = (y < 0)? -y : y;
  1597.   int bw = ay / I_SHIFT;
  1598.   int sw = ay % I_SHIFT;
  1599.  
  1600.   if (y > 0)
  1601.   {
  1602.     int rl = bw + xl + 1;
  1603.     if (xrsame)
  1604.       r = Iresize(r, rl);
  1605.     else
  1606.       r = Icalloc(r, rl);
  1607.  
  1608.     unsigned short* botr = r->s;
  1609.     unsigned short* rs = &(botr[rl - 1]);
  1610.     const unsigned short* botx = (xrsame)? botr : x->s;
  1611.     const unsigned short* xs = &(botx[xl - 1]);
  1612.     unsigned long a = 0;
  1613.     while (xs >= botx)
  1614.     {
  1615.       a = up(a) | ((unsigned long)(*xs--) << sw);
  1616.       *rs-- = extract(down(a));
  1617.     }
  1618.     *rs-- = extract(a);
  1619.     while (rs >= botr)
  1620.       *rs-- = 0;
  1621.   }
  1622.   else
  1623.   {
  1624.     int rl = xl - bw;
  1625.     if (rl < 0)
  1626.       r = Icopy_zero(r);
  1627.     else
  1628.     {
  1629.       if (xrsame)
  1630.         r = Iresize(r, rl);
  1631.       else
  1632.         r = Icalloc(r, rl);
  1633.       int rw = I_SHIFT - sw;
  1634.       unsigned short* rs = r->s;
  1635.       unsigned short* topr = &(rs[rl]);
  1636.       const unsigned short* botx = (xrsame)? rs : x->s;
  1637.       const unsigned short* xs =  &(botx[bw]);
  1638.       const unsigned short* topx = &(botx[xl]);
  1639.       unsigned long a = (unsigned long)(*xs++) >> sw;
  1640.       while (xs < topx)
  1641.       {
  1642.         a |= (unsigned long)(*xs++) << rw;
  1643.         *rs++ = extract(a);
  1644.         a = down(a);
  1645.       }
  1646.       *rs++ = extract(a);
  1647.       if (xrsame) topr = (unsigned short*)topx;
  1648.       while (rs < topr)
  1649.         *rs++ = 0;
  1650.     }
  1651.   }
  1652.   r->sgn = rsgn;
  1653.   Icheck(r);
  1654.   return r;
  1655. }
  1656.  
  1657. IntRep* lshift(const IntRep* x, const IntRep* yy, int negatey, IntRep* r)
  1658. {
  1659.   long y = Itolong(yy);
  1660.   if (negatey)
  1661.     y = -y;
  1662.  
  1663.   return lshift(x, y, r);
  1664. }
  1665.  
  1666. IntRep* bitop(const IntRep* x, const IntRep* y, IntRep* r, char op)
  1667. {
  1668.   nonnil(x);
  1669.   nonnil(y);
  1670.   int xl = x->len;
  1671.   int yl = y->len;
  1672.   int xsgn = x->sgn;
  1673.   int xrsame = x == r;
  1674.   int yrsame = y == r;
  1675.   if (xrsame || yrsame)
  1676.     r = Iresize(r, calc_len(xl, yl, 0));
  1677.   else
  1678.     r = Icalloc(r, calc_len(xl, yl, 0));
  1679.   r->sgn = xsgn;
  1680.   unsigned short* rs = r->s;
  1681.   unsigned short* topr = &(rs[r->len]);
  1682.   const unsigned short* as;
  1683.   const unsigned short* bs;
  1684.   const unsigned short* topb;
  1685.   if (xl >= yl)
  1686.   {
  1687.     as = (xrsame)? rs : x->s;
  1688.     bs = (yrsame)? rs : y->s;
  1689.     topb = &(bs[yl]);
  1690.   }
  1691.   else
  1692.   {
  1693.     bs = (xrsame)? rs : x->s;
  1694.     topb = &(bs[xl]);
  1695.     as = (yrsame)? rs : y->s;
  1696.   }
  1697.  
  1698.   switch (op)
  1699.   {
  1700.   case '&':
  1701.     while (bs < topb) *rs++ = *as++ & *bs++;
  1702.     while (rs < topr) *rs++ = 0;
  1703.     break;
  1704.   case '|':
  1705.     while (bs < topb) *rs++ = *as++ | *bs++;
  1706.     while (rs < topr) *rs++ = *as++;
  1707.     break;
  1708.   case '^':
  1709.     while (bs < topb) *rs++ = *as++ ^ *bs++;
  1710.     while (rs < topr) *rs++ = *as++;
  1711.     break;
  1712.   }
  1713.   Icheck(r);
  1714.   return r;
  1715. }
  1716.  
  1717. IntRep* bitop(const IntRep* x, long y, IntRep* r, char op)
  1718. {
  1719.   nonnil(x);
  1720.   unsigned short tmp[SHORT_PER_LONG];
  1721.   unsigned long u;
  1722.   int newsgn;
  1723.   if (newsgn = (y >= 0))
  1724.     u = y;
  1725.   else
  1726.     u = -y;
  1727.   
  1728.   int l = 0;
  1729.   while (u != 0)
  1730.   {
  1731.     tmp[l++] = extract(u);
  1732.     u = down(u);
  1733.   }
  1734.  
  1735.   int xl = x->len;
  1736.   int yl = l;
  1737.   int xsgn = x->sgn;
  1738.   int xrsame = x == r;
  1739.   if (xrsame)
  1740.     r = Iresize(r, calc_len(xl, yl, 0));
  1741.   else
  1742.     r = Icalloc(r, calc_len(xl, yl, 0));
  1743.   r->sgn = xsgn;
  1744.   unsigned short* rs = r->s;
  1745.   unsigned short* topr = &(rs[r->len]);
  1746.   const unsigned short* as;
  1747.   const unsigned short* bs;
  1748.   const unsigned short* topb;
  1749.   if (xl >= yl)
  1750.   {
  1751.     as = (xrsame)? rs : x->s;
  1752.     bs = tmp;
  1753.     topb = &(bs[yl]);
  1754.   }
  1755.   else
  1756.   {
  1757.     bs = (xrsame)? rs : x->s;
  1758.     topb = &(bs[xl]);
  1759.     as = tmp;
  1760.   }
  1761.  
  1762.   switch (op)
  1763.   {
  1764.   case '&':
  1765.     while (bs < topb) *rs++ = *as++ & *bs++;
  1766.     while (rs < topr) *rs++ = 0;
  1767.     break;
  1768.   case '|':
  1769.     while (bs < topb) *rs++ = *as++ | *bs++;
  1770.     while (rs < topr) *rs++ = *as++;
  1771.     break;
  1772.   case '^':
  1773.     while (bs < topb) *rs++ = *as++ ^ *bs++;
  1774.     while (rs < topr) *rs++ = *as++;
  1775.     break;
  1776.   }
  1777.   Icheck(r);
  1778.   return r;
  1779. }
  1780.  
  1781.  
  1782.  
  1783. IntRep*  compl(const IntRep* src, IntRep* r)
  1784. {
  1785.   nonnil(src);
  1786.   r = Icopy(r, src);
  1787.   unsigned short* s = r->s;
  1788.   unsigned short* top = &(s[r->len - 1]);
  1789.   while (s < top)
  1790.   {
  1791.     unsigned short cmp = ~(*s);
  1792.     *s++ = cmp;
  1793.   }
  1794.   unsigned short a = *s;
  1795.   unsigned short b = 0;
  1796.   while (a != 0)
  1797.   {
  1798.     b <<= 1;
  1799.     if (!(a & 1)) b |= 1;
  1800.     a >>= 1;
  1801.   }
  1802.   *s = b;
  1803.   Icheck(r);
  1804.   return r;
  1805. }
  1806.  
  1807. void (setbit)(Integer& x, long b)
  1808. {
  1809.   if (b >= 0)
  1810.   {
  1811.     int bw = (unsigned long)b / I_SHIFT;
  1812.     int sw = (unsigned long)b % I_SHIFT;
  1813.     if (x.rep == 0)
  1814.       x.rep = Icalloc(0, bw + 1);
  1815.     else if (x.rep->len < bw)
  1816.     {
  1817.       int xl = x.rep->len;
  1818.       x.rep = Iresize(x.rep, calc_len(xl, bw+1, 0));
  1819.     }
  1820.     x.rep->s[bw] |= (1 << sw);
  1821.     Icheck(x.rep);
  1822.   }
  1823. }
  1824.  
  1825. void clearbit(Integer& x, long b)
  1826. {
  1827.   if (b >= 0)
  1828.   {
  1829.     int bw = (unsigned long)b / I_SHIFT;
  1830.     int sw = (unsigned long)b % I_SHIFT;
  1831.     if (x.rep == 0)
  1832.       x.rep = Icalloc(0, bw + 1);
  1833.     else if (x.rep->len < bw)
  1834.     {
  1835.       int xl = x.rep->len;
  1836.       x.rep = Iresize(x.rep, calc_len(xl, bw+1, 0));
  1837.     }
  1838.     x.rep->s[bw] &= ~(1 << sw);
  1839.     Icheck(x.rep);
  1840.   }
  1841. }
  1842.  
  1843. int testbit(const Integer& x, long b)
  1844. {
  1845.   if (x.rep != 0 && b >= 0)
  1846.   {
  1847.     int bw = (unsigned long)b / I_SHIFT;
  1848.     int sw = (unsigned long)b % I_SHIFT;
  1849.     return (bw < x.rep->len && (x.rep->s[bw] & (1 << sw)) != 0);
  1850.   }
  1851.   else
  1852.     return 0;
  1853. }
  1854.  
  1855. // A  version of knuth's algorithm B / ex. 4.5.3.34
  1856. // A better version that doesn't bother shifting all of `t' forthcoming
  1857.  
  1858. IntRep* gcd(const IntRep* x, const IntRep* y)
  1859. {
  1860.   nonnil(x);
  1861.   nonnil(y);
  1862.   int ul = x->len;
  1863.   int vl = y->len;
  1864.   
  1865.   if (vl == 0)
  1866.     return Ialloc(0, x->s, ul, I_POSITIVE, ul);
  1867.   else if (ul == 0)
  1868.     return Ialloc(0, y->s, vl, I_POSITIVE, vl);
  1869.  
  1870.   IntRep* u = Ialloc(0, x->s, ul, I_POSITIVE, ul);
  1871.   IntRep* v = Ialloc(0, y->s, vl, I_POSITIVE, vl);
  1872.  
  1873. // find shift so that both not even
  1874.  
  1875.   long k = 0;
  1876.   int l = (ul <= vl)? ul : vl;
  1877.   int cont = 1;
  1878.   for (int i = 0;  i < l && cont; ++i)
  1879.   {
  1880.     unsigned long a =  (i < ul)? u->s[i] : 0;
  1881.     unsigned long b =  (i < vl)? v->s[i] : 0;
  1882.     for (int j = 0; j < I_SHIFT; ++j)
  1883.     {
  1884.       if ((a | b) & 1)
  1885.       {
  1886.         cont = 0;
  1887.         break;
  1888.       }
  1889.       else
  1890.       {
  1891.         ++k;
  1892.         a >>= 1;
  1893.         b >>= 1;
  1894.       }
  1895.     }
  1896.   }
  1897.  
  1898.   if (k != 0)
  1899.   {
  1900.     u = lshift(u, -k, u);
  1901.     v = lshift(v, -k, v);
  1902.   }
  1903.  
  1904.   IntRep* t;
  1905.   if (u->s[0] & 01)
  1906.     t = Ialloc(0, v->s, v->len, !v->sgn, v->len);
  1907.   else
  1908.     t = Ialloc(0, u->s, u->len, u->sgn, u->len);
  1909.  
  1910.   while (t->len != 0)
  1911.   {
  1912.     long s = 0;                 // shift t until odd
  1913.     cont = 1;
  1914.     int tl = t->len;
  1915.     for (i = 0; i < tl && cont; ++i)
  1916.     {
  1917.       unsigned long a = t->s[i];
  1918.       for (int j = 0; j < I_SHIFT; ++j)
  1919.       {
  1920.         if (a & 1)
  1921.         {
  1922.           cont = 0;
  1923.           break;
  1924.         }
  1925.         else
  1926.         {
  1927.           ++s;
  1928.           a >>= 1;
  1929.         }
  1930.       }
  1931.     }
  1932.  
  1933.     if (s != 0) t = lshift(t, -s, t);
  1934.  
  1935.     if (t->sgn == I_POSITIVE)
  1936.     {
  1937.       u = Icopy(u, t);
  1938.       t = add(t, 0, v, 1, t);
  1939.     }
  1940.     else
  1941.     {
  1942.       v = Ialloc(v, t->s, t->len, !t->sgn, t->len);
  1943.       t = add(t, 0, u, 0, t);
  1944.     }
  1945.   }
  1946.   if (!STATIC_IntRep(t)) delete t;
  1947.   if (!STATIC_IntRep(v)) delete v;
  1948.   if (k != 0) u = lshift(u, k, u);
  1949.   return u;
  1950. }
  1951.  
  1952.  
  1953.  
  1954. long lg(const IntRep* x)
  1955. {
  1956.   nonnil(x);
  1957.   int xl = x->len;
  1958.   if (xl == 0)
  1959.     return 0;
  1960.  
  1961.   long l = (xl - 1) * I_SHIFT - 1;
  1962.   unsigned short a = x->s[xl-1];
  1963.  
  1964.   while (a != 0)
  1965.   {
  1966.     a = a >> 1;
  1967.     ++l;
  1968.   }
  1969.   return l;
  1970. }
  1971.   
  1972. IntRep* power(const IntRep* x, long y, IntRep* r)
  1973. {
  1974.   nonnil(x);
  1975.   int sgn;
  1976.   if (x->sgn == I_POSITIVE || (!(y & 1)))
  1977.     sgn = I_POSITIVE;
  1978.   else
  1979.     sgn = I_NEGATIVE;
  1980.  
  1981.   int xl = x->len;
  1982.  
  1983.   if (y == 0 || (xl == 1 && x->s[0] == 1))
  1984.     r = Icopy_one(r, sgn);
  1985.   else if (xl == 0 || y < 0)
  1986.     r = Icopy_zero(r);
  1987.   else if (y == 1 || y == -1)
  1988.     r = Icopy(r, x);
  1989.   else
  1990.   {
  1991.     int maxsize = ((lg(x) + 1) * y) / I_SHIFT + 2;     // pre-allocate space
  1992.     IntRep* b = Ialloc(0, x->s, xl, I_POSITIVE, maxsize);
  1993.     b->len = xl;
  1994.     r = Icalloc(r, maxsize);
  1995.     r = Icopy_one(r, I_POSITIVE);
  1996.     for(;;)
  1997.     {
  1998.       if (y & 1)
  1999.         r = multiply(r, b, r);
  2000.       if ((y >>= 1) == 0)
  2001.         break;
  2002.       else
  2003.         b = multiply(b, b, b);
  2004.     }
  2005.     if (!STATIC_IntRep(b)) delete b;
  2006.   }
  2007.   r->sgn = sgn;
  2008.   Icheck(r);
  2009.   return r;
  2010. }
  2011.  
  2012. IntRep* abs(const IntRep* src, IntRep* dest)
  2013. {
  2014.   nonnil(src);
  2015.   if (src != dest)
  2016.     dest = Icopy(dest, src);
  2017.   dest->sgn = I_POSITIVE;
  2018.   return dest;
  2019. }
  2020.  
  2021. IntRep* negate(const IntRep* src, IntRep* dest)
  2022. {
  2023.   nonnil(src);
  2024.   if (src != dest)
  2025.     dest = Icopy(dest, src);
  2026.   if (dest->len != 0) 
  2027.     dest->sgn = !dest->sgn;
  2028.   return dest;
  2029. }
  2030.  
  2031. #if defined(__GNUG__) && !defined(NO_NRV)
  2032.  
  2033. Integer sqrt(const Integer& x) return r(x)
  2034. {
  2035.   int s = sign(x);
  2036.   if (s < 0) x.error("Attempted square root of negative Integer");
  2037.   if (s != 0)
  2038.   {
  2039.     r >>= (lg(x) / 2); // get close
  2040.     Integer q;
  2041.     div(x, r, q);
  2042.     while (q < r)
  2043.     {
  2044.       r += q;
  2045.       r >>= 1;
  2046.       div(x, r, q);
  2047.     }
  2048.   }
  2049.   return;
  2050. }
  2051.  
  2052. Integer lcm(const Integer& x, const Integer& y) return r
  2053. {
  2054.   if (!x.initialized() || !y.initialized())
  2055.     x.error("operation on uninitialized Integer");
  2056.   Integer g;
  2057.   if (sign(x) == 0 || sign(y) == 0)
  2058.     g = 1;
  2059.   else 
  2060.     g = gcd(x, y);
  2061.   div(x, g, r);
  2062.   mul(r, y, r);
  2063. }
  2064.  
  2065. #else 
  2066. Integer sqrt(const Integer& x) 
  2067. {
  2068.   Integer r(x);
  2069.   int s = sign(x);
  2070.   if (s < 0) x.error("Attempted square root of negative Integer");
  2071.   if (s != 0)
  2072.   {
  2073.     r >>= (lg(x) / 2); // get close
  2074.     Integer q;
  2075.     div(x, r, q);
  2076.     while (q < r)
  2077.     {
  2078.       r += q;
  2079.       r >>= 1;
  2080.       div(x, r, q);
  2081.     }
  2082.   }
  2083.   return r;
  2084. }
  2085.  
  2086. Integer lcm(const Integer& x, const Integer& y) 
  2087. {
  2088.   Integer r;
  2089.   if (!x.initialized() || !y.initialized())
  2090.     x.error("operation on uninitialized Integer");
  2091.   Integer g;
  2092.   if (sign(x) == 0 || sign(y) == 0)
  2093.     g = 1;
  2094.   else 
  2095.     g = gcd(x, y);
  2096.   div(x, g, r);
  2097.   mul(r, y, r);
  2098.   return r;
  2099. }
  2100.  
  2101. #endif
  2102.  
  2103.  
  2104.  
  2105. IntRep* atoIntRep(const char* s, int base)
  2106. {
  2107.   int sl = strlen(s);
  2108.   IntRep* r = Icalloc(0, sl * (lg(base) + 1) / I_SHIFT + 1);
  2109.   if (s != 0)
  2110.   {
  2111.     char sgn;
  2112.     while (isspace(*s)) ++s;
  2113.     if (*s == '-')
  2114.     {
  2115.       sgn = I_NEGATIVE;
  2116.       s++;
  2117.     }
  2118.     else if (*s == '+')
  2119.     {
  2120.       sgn = I_POSITIVE;
  2121.       s++;
  2122.     }
  2123.     else
  2124.       sgn = I_POSITIVE;
  2125.     for (;;)
  2126.     {
  2127.       long digit;
  2128.       if (*s >= '0' && *s <= '9') digit = *s - '0';
  2129.       else if (*s >= 'a' && *s <= 'z') digit = *s - 'a' + 10;
  2130.       else if (*s >= 'A' && *s <= 'Z') digit = *s - 'A' + 10;
  2131.       else break;
  2132.       if (digit >= base) break;
  2133.       r = multiply(r, base, r);
  2134.       r = add(r, 0, digit, r);
  2135.       ++s;
  2136.     }
  2137.     r->sgn = sgn;
  2138.   }
  2139.   return r;
  2140. }
  2141.  
  2142.  
  2143.  
  2144. extern AllocRing _libgxx_fmtq;
  2145.  
  2146. char* Itoa(const IntRep* x, int base, int width)
  2147. {
  2148.   int fmtlen = (x->len + 1) * I_SHIFT / lg(base) + 4 + width;
  2149.   char* fmtbase = (char *) _libgxx_fmtq.alloc(fmtlen);
  2150.   char* f = cvtItoa(x, fmtbase, fmtlen, base, 0, width, 0, ' ', 'X', 0);
  2151.   return f;
  2152. }
  2153.  
  2154. ostream& operator << (ostream& s, const Integer& y)
  2155. {
  2156. #ifdef _OLD_STREAMS
  2157.   return s << Itoa(y.rep);
  2158. #else
  2159.   if (s.opfx())
  2160.     {
  2161.       int base = (s.flags() & ios::oct) ? 8 : (s.flags() & ios::hex) ? 16 : 10;
  2162.       int width = s.width();
  2163.       y.printon(s, base, width);
  2164.     }
  2165.   return s;
  2166. #endif
  2167. }
  2168.  
  2169. void Integer::printon(ostream& s, int base /* =10 */, int width /* =0 */) const
  2170. {
  2171.   int align_right = !(s.flags() & ios::left);
  2172.   int showpos = s.flags() & ios::showpos;
  2173.   int showbase = s.flags() & ios::showbase;
  2174.   char fillchar = s.fill();
  2175.   char Xcase = (s.flags() & ios::uppercase)? 'X' : 'x';
  2176.   const IntRep* x = rep;
  2177.   int fmtlen = (x->len + 1) * I_SHIFT / lg(base) + 4 + width;
  2178.   char* fmtbase = new char[fmtlen];
  2179.   char* f = cvtItoa(x, fmtbase, fmtlen, base, showbase, width, align_right,
  2180.             fillchar, Xcase, showpos);
  2181.   s.write(f, fmtlen);
  2182.   delete fmtbase;
  2183. }
  2184.  
  2185. char*  cvtItoa(const IntRep* x, char* fmt, int& fmtlen, int base, int showbase,
  2186.               int width, int align_right, char fillchar, char Xcase, 
  2187.               int showpos)
  2188. {
  2189.   char* e = fmt + fmtlen - 1;
  2190.   char* s = e;
  2191.   *--s = 0;
  2192.  
  2193.   if (x->len == 0)
  2194.     *--s = '0';
  2195.   else
  2196.   {
  2197.     IntRep* z = Icopy(0, x);
  2198.  
  2199.     // split division by base into two parts: 
  2200.     // first divide by biggest power of base that fits in an unsigned short,
  2201.     // then use straight signed div/mods from there. 
  2202.  
  2203.     // find power
  2204.     int bpower = 1;
  2205.     unsigned short b = base;
  2206.     unsigned short maxb = I_MAXNUM / base;
  2207.     while (b < maxb)
  2208.     {
  2209.       b *= base;
  2210.       ++bpower;
  2211.     }
  2212.     for(;;)
  2213.     {
  2214.       int rem = unscale(z->s, z->len, b, z->s);
  2215.       Icheck(z);
  2216.       if (z->len == 0)
  2217.       {
  2218.         while (rem != 0)
  2219.         {
  2220.           char ch = rem % base;
  2221.           rem /= base;
  2222.           if (ch >= 10)
  2223.             ch += 'a' - 10;
  2224.           else
  2225.             ch += '0';
  2226.           *--s = ch;
  2227.         }
  2228.     if (!STATIC_IntRep(z)) delete z;
  2229.         break;
  2230.       }
  2231.       else
  2232.       {
  2233.         for (int i = 0; i < bpower; ++i)
  2234.         {
  2235.           char ch = rem % base;
  2236.           rem /= base;
  2237.           if (ch >= 10)
  2238.             ch += 'a' - 10;
  2239.           else
  2240.             ch += '0';
  2241.           *--s = ch;
  2242.         }
  2243.       }
  2244.     }
  2245.   }
  2246.  
  2247.   if (base == 8 && showbase) 
  2248.     *--s = '0';
  2249.   else if (base == 16 && showbase) 
  2250.   { 
  2251.     *--s = Xcase; 
  2252.     *--s = '0'; 
  2253.   }
  2254.   if (x->sgn == I_NEGATIVE) *--s = '-';
  2255.   else if (showpos) *--s = '+';
  2256.   int w = e - s - 1;
  2257.   if (!align_right || w >= width)
  2258.   {
  2259.     while (w++ < width)
  2260.       *--s = fillchar;
  2261.     fmtlen = e - s - 1;
  2262.     return s;
  2263.   }
  2264.   else
  2265.   {
  2266.     char* p = fmt;
  2267.     int gap = s - p;
  2268.     for (char* t = s; *t != 0; ++t, ++p) *p = *t;
  2269.     while (w++ < width) *p++ = fillchar;
  2270.     *p = 0;
  2271.     fmtlen = p - fmt;
  2272.     return fmt;
  2273.   }
  2274. }
  2275.  
  2276. char* dec(const Integer& x, int width)
  2277. {
  2278.   return Itoa(x, 10, width);
  2279. }
  2280.  
  2281. char* oct(const Integer& x, int width)
  2282. {
  2283.   return Itoa(x, 8, width);
  2284. }
  2285.  
  2286. char* hex(const Integer& x, int width)
  2287. {
  2288.   return Itoa(x, 16, width);
  2289. }
  2290.  
  2291. istream& operator >> (istream& s, Integer& y)
  2292. {
  2293. #ifdef _OLD_STREAMS
  2294.   if (!s.good())
  2295.     return s;
  2296. #else
  2297.   if (!s.ipfx(0))
  2298.   {
  2299.     s.set(ios::failbit);
  2300.     return s;
  2301.   }
  2302. #endif
  2303.   s >> ws;
  2304.   if (!s.good())
  2305.   {
  2306.     s.set(_fail);
  2307.     return s;
  2308.   }
  2309.   
  2310. #ifdef _OLD_STREAMS
  2311.   int know_base = 0;
  2312.   int base = 10;
  2313. #else
  2314.   int know_base = s.flags() & (ios::oct | ios::hex | ios::dec);
  2315.   int base = (s.flags() & ios::oct) ? 8 : (s.flags() & ios::hex) ? 16 : 10;
  2316. #endif
  2317.  
  2318.   int got_one = 0;
  2319.   char sgn = 0;
  2320.   char ch;
  2321.   y.rep = Icopy_zero(y.rep);
  2322.  
  2323.   while (s.get(ch))
  2324.   {
  2325.     if (ch == '-')
  2326.     {
  2327.       if (sgn == 0)
  2328.         sgn = '-';
  2329.       else
  2330.         break;
  2331.     }
  2332.     else if (!know_base & !got_one && ch == '0')
  2333.       base = 8;
  2334.     else if (!know_base & !got_one && base == 8 && (ch == 'X' || ch == 'x'))
  2335.       base = 16;
  2336.     else if (base == 8)
  2337.     {
  2338.       if (ch >= '0' && ch <= '7')
  2339.       {
  2340.         long digit = ch - '0';
  2341.         y <<= 3;
  2342.         y += digit;
  2343.         got_one = 1;
  2344.       }
  2345.       else
  2346.         break;
  2347.     }
  2348.     else if (base == 16)
  2349.     {
  2350.       long digit;
  2351.       if (ch >= '0' && ch <= '9')
  2352.         digit = ch - '0';
  2353.       else if (ch >= 'A' && ch <= 'F')
  2354.         digit = ch - 'A' + 10;
  2355.       else if (ch >= 'a' && ch <= 'f')
  2356.         digit = ch - 'a' + 10;
  2357.       else
  2358.         digit = base;
  2359.       if (digit < base)
  2360.       {
  2361.         y <<= 4;
  2362.         y += digit;
  2363.         got_one = 1;
  2364.       }
  2365.       else
  2366.         break;
  2367.     }
  2368.     else if (base == 10)
  2369.     {
  2370.       if (ch >= '0' && ch <= '9')
  2371.       {
  2372.         long digit = ch - '0';
  2373.         y *= 10;
  2374.         y += digit;
  2375.         got_one = 1;
  2376.       }
  2377.       else
  2378.         break;
  2379.     }
  2380.     else
  2381.       abort(); // can't happen for now
  2382.   }
  2383.   if (s.good())
  2384.     s.putback(ch);
  2385.   if (!got_one)
  2386.     s.set(_fail);
  2387.  
  2388.   if (sgn == '-')
  2389.     y.negate();
  2390.  
  2391.   return s;
  2392. }
  2393.  
  2394. int Integer::OK() const
  2395. {
  2396.   if (rep != 0)
  2397.     {
  2398.       int l = rep->len;
  2399.       int s = rep->sgn;
  2400.       int v = l <= rep->sz || STATIC_IntRep(rep);    // length within bounds
  2401.       v &= s == 0 || s == 1;        // legal sign
  2402.       Icheck(rep);                  // and correctly adjusted
  2403.       v &= rep->len == l;
  2404.       v &= rep->sgn == s;
  2405.       if (v)
  2406.       return v;
  2407.     }
  2408.   error("invariant failure");
  2409.   return 0;
  2410. }
  2411.  
  2412. void Integer::error(const char* msg) const
  2413. {
  2414.   (*lib_error_handler)("Integer", msg);
  2415. }
  2416.  
  2417.