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