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