_integer.c
上传用户:gzelex
上传日期:2007-01-07
资源大小:707k
文件大小:39k
开发平台:

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _integer.c
  6. +
  7. +  Copyright (c) 1995  by  Max-Planck-Institut fuer Informatik
  8. +  Im Stadtwald, 66123 Saarbruecken, Germany     
  9. +  All rights reserved.
  10. *******************************************************************************/
  11. //------------------------------------------------------------------------------
  12. //
  13. //  integer:  big integers
  14. //
  15. //  by Christian Uhrig and Stefan Naeher   (1994/1995)
  16. //
  17. //  - 32 bit (unsigned long) vector representation
  18. //  - use of a handle class concept (to avoid copy overhead)
  19. //  - use of the LEDA memory management
  20. //  - sparc assembler code for 32 bit multiplication and division
  21. //  - Karatsuba multiplication for long integers
  22. //  - loop unrolling
  23. //
  24. //  - sparc assembler for add and sub (S. Naeher, 1995)
  25. //
  26. //------------------------------------------------------------------------------
  27. #include <LEDA/integer.h>
  28. #include <math.h>
  29. #include <ctype.h>
  30. typedef int_word_type word;
  31. typedef unsigned int sz_t;
  32. #define WORD_LENGTH  32 
  33. #define HALF_LENGTH  16 
  34. #define KARA_LIMIT    8 
  35. #define MAX_WORD     0xFFFFFFFF
  36. #define RIGHT_MASK   0x0000FFFF
  37. #define LEFT_MASK    0xFFFF0000
  38. #define LOW_WORD(w)  (w & RIGHT_MASK)
  39. #define HIGH_WORD(w) (w >> HALF_LENGTH)
  40. enum {ZERO=0, NEGATIVE=-1, POSITIVE=1 };
  41. const double pow32 = ldexp(1,WORD_LENGTH);
  42. inline int next_power(int s)
  43. { int p = 1;
  44.   while (p < s) p <<= 1;
  45.   return p;
  46. }
  47. void delete_integer_rep(integer_rep* p)
  48. { int s = sizeof(integer_rep) + (p->size-1)*sizeof(unsigned long);
  49.   if (s < 256)
  50.      deallocate_bytes(p,s);
  51.   else
  52.      delete[] p;
  53. }
  54. integer::integer()
  55. { PTR = new_integer_rep(1);
  56.   PTR->vec[0] = 0;
  57.   PTR->sign = ZERO;
  58.   PTR->used = 0;
  59.  }
  60. integer::integer(unsigned int n)
  61. {
  62.   PTR = new_integer_rep(1);
  63.   PTR->vec[0] = n;
  64.   if (n == 0)
  65.      { PTR->sign = ZERO;
  66.        PTR->used = 0; }
  67.   else
  68.      { PTR->sign = POSITIVE;
  69.        PTR->used = 1; }
  70. }
  71. integer::integer(int n)
  72. {
  73.   PTR = new_integer_rep(1);
  74.   PTR->used = 1;
  75.   PTR->vec[0] = n;
  76.   PTR->sign = POSITIVE;
  77.   if (n == 0)
  78.   { PTR->sign = ZERO;
  79.     PTR->used = 0;
  80.    }
  81.   if (n < 0) 
  82.   { PTR->sign = NEGATIVE;
  83.     PTR->vec[0] = -n;
  84.    }
  85. }
  86. integer::integer(long n)
  87. {
  88.   PTR = new_integer_rep(1);
  89.   PTR->used = 1;
  90.   PTR->vec[0] = n;
  91.   PTR->sign = POSITIVE;
  92.   if (n == 0)
  93.   { PTR->sign = ZERO;
  94.     PTR->used = 0;
  95.    }
  96.   if (n < 0) 
  97.   { PTR->sign = NEGATIVE;
  98.     PTR->vec[0] = -n;
  99.    }
  100. }
  101. integer::integer(unsigned long n)
  102. {
  103.   PTR = new_integer_rep(1);
  104.   if (n == 0)
  105.   { PTR->sign = ZERO;
  106.     PTR->used = 0;
  107.    }
  108.   else
  109.   { PTR->sign = POSITIVE;
  110.     PTR->used = 1;
  111.     PTR->vec[0] = n;
  112.    }
  113. }
  114. integer::integer(double x) 
  115.   int sig = POSITIVE;
  116.   if (x < 0) 
  117.   { sig = NEGATIVE;
  118.     x = -x;
  119.    }
  120.   if (x < 1)
  121.   { PTR = new_integer_rep(1);
  122.     PTR->used = 0;
  123.     PTR->sign = ZERO;
  124.     return;
  125.    }
  126.   if (x < double(MAX_WORD))
  127.   { PTR = new_integer_rep(1);
  128.     PTR->vec[0] = word(x);
  129.     PTR->used = 1;
  130.     PTR->sign = sig;
  131.     return;
  132.    }
  133.   int expt;
  134.   double mantissa = frexp(x, &expt);
  135.   double int_mant;
  136.   int r = expt % WORD_LENGTH;
  137.   int q = expt / WORD_LENGTH;
  138.   int used = q;
  139.   if (r) used++;
  140.   int sz = next_power(used);
  141.   PTR = new_integer_rep(sz);
  142.   PTR->used = used;
  143.   PTR->sign = sig;
  144.   word* p = PTR->vec+used-1;
  145.   if (r)
  146.   { mantissa *= ldexp(1,r);
  147.     mantissa = modf(mantissa, &int_mant);
  148.     *p--= (unsigned long)int_mant; // first r bits
  149.    }
  150.   while (q--)
  151.     if (mantissa != 0)
  152.     { mantissa *= pow32;
  153.       mantissa = modf(mantissa, &int_mant);
  154.       *p-- = (unsigned long)int_mant; // next 32 bits
  155.      }
  156.     else *p-- = 0;
  157.   if (used == 0) PTR->sign = ZERO;
  158. }
  159. //------------------------------------------------------------------------------
  160. // local functions
  161. //------------------------------------------------------------------------------
  162. inline word DivTwoWordsByOne(word high, word low, word D, word* q)
  163.   // precondition:  high < D  
  164.   // *q = [high,low] / D, returns remainder
  165.   // the result has at most 32 bits  
  166.   // we can compute it with double precision floating point division
  167.   double H = high;
  168.   double L = low;
  169.   word   Q = word((H/D)*pow32 + L/D);
  170.   D *= Q;
  171.   *q = Q;
  172.   return low-D;
  173. }
  174. static int absolute_cmp(word* a, int a_used, word* b, int b_used)
  175.   if (a_used > b_used) return  1;
  176.   if (a_used < b_used) return -1;
  177.   word* ap = a + a_used;
  178.   word* bp = b + b_used;
  179.   while(ap > a)
  180.   { word A = *--ap;
  181.     word B = *--bp;
  182.     if (A > B) return  1;
  183.     if (A < B) return -1;
  184.    }
  185.   return 0;
  186. }
  187. static void Init_Vector(word* a, sz_t a_used)
  188.   switch (a_used % 16)
  189.   { case 15:*a++ = 0;
  190.     case 14:*a++ = 0;
  191.     case 13:*a++ = 0;
  192.     case 12:*a++ = 0;
  193.     case 11:*a++ = 0;
  194.     case 10:*a++ = 0;
  195.     case  9:*a++ = 0;
  196.     case  8:*a++ = 0;
  197.     case  7:*a++ = 0;
  198.     case  6:*a++ = 0;
  199.     case  5:*a++ = 0;
  200.     case  4:*a++ = 0;
  201.     case  3:*a++ = 0;
  202.     case  2:*a++ = 0;
  203.     case  1:*a++ = 0;
  204.    }
  205.   int n = a_used / 16;
  206.   while (n--)
  207.     { *a++ = 0;  *a++ = 0;  *a++ = 0;  *a++ = 0;
  208.       *a++ = 0;  *a++ = 0;  *a++ = 0;  *a++ = 0;
  209.       *a++ = 0;  *a++ = 0;  *a++ = 0;  *a++ = 0;
  210.       *a++ = 0;  *a++ = 0;  *a++ = 0;  *a++ = 0; }
  211. }
  212. static word* Copy_Vector(word* a, word* b, sz_t b_used)
  213.   // copy b[0..b_used-1] to a[]
  214.   switch (b_used % 16)
  215.   { case 15:*a++ = *b++;
  216.     case 14:*a++ = *b++;
  217.     case 13:*a++ = *b++;
  218.     case 12:*a++ = *b++;
  219.     case 11:*a++ = *b++;
  220.     case 10:*a++ = *b++;
  221.     case  9:*a++ = *b++;
  222.     case  8:*a++ = *b++;
  223.     case  7:*a++ = *b++;
  224.     case  6:*a++ = *b++;
  225.     case  5:*a++ = *b++;
  226.     case  4:*a++ = *b++;
  227.     case  3:*a++ = *b++;
  228.     case  2:*a++ = *b++;
  229.     case  1:*a++ = *b++; }
  230.   int n = b_used / 16;
  231.   while (n--)
  232.     { *a++ = *b++;  *a++ = *b++;  *a++ = *b++;  *a++ = *b++;
  233.       *a++ = *b++;  *a++ = *b++;  *a++ = *b++;  *a++ = *b++;
  234.       *a++ = *b++;  *a++ = *b++;  *a++ = *b++;  *a++ = *b++;
  235.       *a++ = *b++;  *a++ = *b++;  *a++ = *b++;  *a++ = *b++; }
  236.   return a;
  237. }
  238. static void Print_Vector(word* a, int a_used, ostream& out) 
  239. {
  240.   char* digits   = new char[10*a_used];
  241.   word* tmp      = new word[a_used];
  242.   word* tmp_high = Copy_Vector(tmp,a,a_used) - 1;
  243.   int i = 0;
  244.   while (tmp_high >= tmp)
  245.   { word r = 0;
  246.     for (word* p = tmp_high; p >= tmp; p--) 
  247.        r = DivTwoWordsByOne(r,*p,10,p);
  248.     if (*tmp_high == 0) tmp_high--;
  249.     digits[i++] = '0' + char(r);
  250.    }
  251.   while (i--) out << digits[i];
  252.   delete[] digits;
  253.   delete[] tmp;
  254. }
  255. #if defined(sparc)
  256. //------------------------------------------------------------------------------
  257. // sparc assembler code
  258. //------------------------------------------------------------------------------
  259. // _sparc_mult.s: Multiply_Words & Mult_Inner_Loop
  260. // _sparc_div.s : Div_Inner_Loop
  261. // _sparc_add.s : School_Add
  262. // _sparc_sub.s : School_Sub
  263. //------------------------------------------------------------------------------
  264. #if defined(__svr4__)
  265. #define Multiply_Words  _Multiply_Words
  266. #define Mult_Inner_Loop _Mult_Inner_Loop
  267. #define Div_Inner_Loop  _Div_Inner_Loop
  268. #define School_Add      _School_Add
  269. #define School_Sub      _School_Sub
  270. #endif
  271. extern "C" sz_t School_Add(word*,sz_t,word*,sz_t,word*);
  272. extern "C" sz_t School_Sub(word*,sz_t,word*,sz_t,word*);
  273. extern "C" word Multiply_Words(word a, word b, word* high);
  274. extern "C" word Mult_Inner_Loop(word* p, word* a, word* a_stop, word B);
  275. extern "C" word Div_Inner_Loop(word* p, word* a, word* a_stop, word B);
  276. #else
  277. /* if not sparc */
  278. inline word Multiply_Words(word a, word b, word* high)
  279. { word al = LOW_WORD(a);
  280.   word ah = HIGH_WORD(a);
  281.   word bl = LOW_WORD(b);
  282.   word bh = HIGH_WORD(b);
  283.   word c,L,H;
  284.   c = bl*al;           
  285.   L = LOW_WORD(c);
  286.   c = HIGH_WORD(c) + bl*ah;
  287.   H = HIGH_WORD(c);
  288.   c = LOW_WORD(c)  + bh*al;
  289.   L |= (LOW_WORD(c) << HALF_LENGTH);
  290.   *high =  H + HIGH_WORD(c) + bh*ah;
  291.   return L;
  292. }
  293. inline word Mult_Inner_Loop(word* p, word* a, word* a_stop, word B)
  294. {
  295.    // p[] += a[]*B, return carry
  296.    word low,high;
  297.    word carry = 0;
  298.    while (a < a_stop)
  299.    { word P = *p;
  300.      low = Multiply_Words(*a++,B,&high);
  301.      P += low;
  302.      if (P < low )  high++; // carry in addition
  303.      P += carry;
  304.      if (P < carry) high++; // carry in addition
  305.      *p++ = P;
  306.      carry = high;
  307.    }
  308.    *p = carry;
  309.    return carry;
  310. }
  311. inline word Div_Inner_Loop(word* p, word* a, word* a_stop, word B)
  312.    // p[] -= a[]*B, return carry
  313.    word low,high;
  314.    word carry = 0;
  315.    word P;
  316.    while (a < a_stop)
  317.    { P = *p;
  318.      low = Multiply_Words(*a++,B,&high);
  319.      if (P < low) high++;  // carry
  320.      P -= low;
  321.      if (P < carry) high++;  // carry
  322.      P -= carry;
  323.      *p++ = P;
  324.      carry = high;
  325.    }
  326.    P = *p;
  327.    *p = P - carry;
  328.   
  329.    return (P < carry);
  330. }
  331. static sz_t School_Add(word *a, sz_t a_used, word *b, sz_t b_used, word* sum)
  332. {
  333.   // compute sum = a + b   (a_used >= b_used)
  334.   int carry = 0;
  335.   word aa;
  336.   word bb;
  337.   word* s_last = sum + a_used;
  338. #define ADD_LOOP_BODY {
  339.   aa = *a++;
  340.   bb = *b++;
  341.   aa += bb;
  342.   if (carry) { if (++aa > bb) carry = false; }
  343.   else if (aa < bb) carry = true;
  344.   *sum++ = aa; }
  345.   int r = b_used % 16;
  346.   switch (r) { 
  347.       case 15: ADD_LOOP_BODY;
  348.       case 14: ADD_LOOP_BODY;
  349.       case 13: ADD_LOOP_BODY;
  350.       case 12: ADD_LOOP_BODY;
  351.       case 11: ADD_LOOP_BODY;
  352.       case 10: ADD_LOOP_BODY;
  353.       case  9: ADD_LOOP_BODY;
  354.       case  8: ADD_LOOP_BODY;
  355.       case  7: ADD_LOOP_BODY;
  356.       case  6: ADD_LOOP_BODY;
  357.       case  5: ADD_LOOP_BODY;
  358.       case  4: ADD_LOOP_BODY;
  359.       case  3: ADD_LOOP_BODY;
  360.       case  2: ADD_LOOP_BODY;
  361.       case  1: ADD_LOOP_BODY;
  362.      }
  363.   int n = b_used / 16;
  364.   while (n--)
  365.   { ADD_LOOP_BODY; ADD_LOOP_BODY; ADD_LOOP_BODY; ADD_LOOP_BODY; 
  366.     ADD_LOOP_BODY; ADD_LOOP_BODY; ADD_LOOP_BODY; ADD_LOOP_BODY; 
  367.     ADD_LOOP_BODY; ADD_LOOP_BODY; ADD_LOOP_BODY; ADD_LOOP_BODY; 
  368.     ADD_LOOP_BODY; ADD_LOOP_BODY; ADD_LOOP_BODY; ADD_LOOP_BODY;
  369.    }
  370.   if (sum != a) // copy rest of a to sum
  371.   { Copy_Vector(sum,a,a_used-b_used);
  372.     *s_last = 0;
  373.    }
  374.   if (carry) // propagate carry
  375.   { while (++*sum == 0) sum++;
  376.     if (sum == s_last) a_used++;
  377.    }
  378.   return a_used;
  379. }
  380. static sz_t School_Sub(word *a, sz_t a_used, word *b, sz_t b_used, word* diff)
  381. {
  382.   // compute diff = a - b    (a > b)
  383. #define SUB_LOOP_BODY {
  384.   aa = *a++;
  385.   bb = *b++;
  386.   if (borrow && ++bb) borrow = false;
  387.   if (aa < bb)  borrow = true;
  388.   *diff++ = aa - bb; }
  389.   word  aa;
  390.   word  bb;
  391.   bool  borrow = false;
  392.   word* d_stop = diff + a_used;
  393.   switch (b_used % 16) 
  394.    { case 15: SUB_LOOP_BODY;
  395.      case 14: SUB_LOOP_BODY;
  396.      case 13: SUB_LOOP_BODY;
  397.      case 12: SUB_LOOP_BODY;
  398.      case 11: SUB_LOOP_BODY;
  399.      case 10: SUB_LOOP_BODY;
  400.      case  9: SUB_LOOP_BODY;
  401.      case  8: SUB_LOOP_BODY;
  402.      case  7: SUB_LOOP_BODY;
  403.      case  6: SUB_LOOP_BODY;
  404.      case  5: SUB_LOOP_BODY;
  405.      case  4: SUB_LOOP_BODY;
  406.      case  3: SUB_LOOP_BODY;
  407.      case  2: SUB_LOOP_BODY;
  408.      case  1: SUB_LOOP_BODY;
  409.     }
  410.   int n = b_used / 16;
  411.   while (n--)
  412.   { SUB_LOOP_BODY; SUB_LOOP_BODY; SUB_LOOP_BODY; SUB_LOOP_BODY; 
  413.     SUB_LOOP_BODY; SUB_LOOP_BODY; SUB_LOOP_BODY; SUB_LOOP_BODY; 
  414.     SUB_LOOP_BODY; SUB_LOOP_BODY; SUB_LOOP_BODY; SUB_LOOP_BODY; 
  415.     SUB_LOOP_BODY; SUB_LOOP_BODY; SUB_LOOP_BODY; SUB_LOOP_BODY;
  416.    }
  417.   if (diff != a) Copy_Vector(diff,a,a_used-b_used);
  418.   if (borrow)
  419.     while (--*diff == MAX_WORD) diff++;
  420.   while (*--d_stop == 0) a_used--;
  421.   return a_used;
  422. }
  423. /* end of not-sparc section */
  424. #endif
  425. static sz_t School_Mult(word *a, sz_t a_used, word *b,int b_used, word* prod) 
  426.   sz_t p_used = a_used + b_used;
  427.   word* a_stop = a + a_used;
  428.   word* b_last = b + b_used - 1;
  429.   Init_Vector(prod,a_used);
  430.   while (b < b_last)
  431.       Mult_Inner_Loop(prod++,a,a_stop,*b++);
  432.   if (Mult_Inner_Loop(prod,a,a_stop,*b) == 0) p_used--;   // no carry
  433.   return p_used;
  434. }
  435. static void Karatsuba(word* prod, word* a, word* b, word* tmp, int n)
  436. {       
  437.  /*  Input: 
  438.                 4n      3n      2n       n        0
  439.                                          A1       A0
  440.                                  +-------+--------+
  441.    a[0..2n-1]                    |  a1   |  a0    |
  442.                                  +-------+--------+
  443.                                          B1       B0
  444.                                  +-------+--------+
  445.    b[0..2n-1]                    |  b1   |  b0    |
  446.                                  +-------+--------+
  447.                                  T2      T1       T0
  448.                  +-------+-------+-------+--------+
  449.    tmp[0..4n-1]  |       |       |       |        |    space for temporaries
  450.                  +-------+-------+-------+--------+
  451.   Output:                P3      P2      P1       P0
  452.                  +-------+-------+-------+--------+
  453.   prod[0..4n-1]  |           a  *  b              | 
  454.                  +-------+-------+-------+--------+
  455.  Let  
  456.          a = a1*B^n + a0 
  457.          b = b1*B^n + b0
  458.  then
  459.        a*b = (a1*b1)*B^2n + (a1*b0)*B^n + (a0*b1)*B^n + (a0*b0)
  460.            = (a0*b0) + (a1*b1)*B^2n + (a1*b1 + a0*b0 + (a1-a0)(b0-b1))*B^n 
  461.        4n      3n      2n       n        0
  462.         +-------+-------+-------+--------+
  463.         |    a1 * b1    |    a0 * b0     |
  464.         +-------+-------+-------+--------+
  465.         +-------+-------+-------+--------+
  466.       + |   0   |    a1 * b1    |   0    |
  467.         +-------+-------+-------+--------+
  468.         +-------+-------+-------+--------+
  469.       + |   0   |    a0 * b0    |   0    |
  470.         +-------+-------+-------+--------+
  471.         +-------+-------+-------+--------+
  472.       + |   0   |(a1-a0)*(b0-b1)|   0    |
  473.         +-------+-------+-------+--------+
  474.      ----------------------------------------
  475.         +--------------------------------+
  476.       = |         a     *     b          |
  477.         +--------------------------------+
  478.    We compute the three partial products a1*b1, a0*b0, and (a1-a0)*(b0-b1)
  479.    recursively as long as n is even and greater or equal to KARA_LIMIT
  480.    and by a call of School_Mult otherwise.
  481.   */
  482.   if (n & 1 || n < KARA_LIMIT)
  483.   { School_Mult(a,2*n,b,2*n,prod);
  484.     return;
  485.    }
  486.   word* A0 = a;
  487.   word* A1 = a + n;
  488.   word* B0 = b;
  489.   word* B1 = b + n;
  490.   word* P0 = prod;
  491.   word* P1 = prod + n;
  492.   word* P2 = prod + 2*n;
  493.   word* P3 = prod + 3*n;
  494.   word* T0 = tmp;
  495.   // word* T1 = tmp + n; (never used)
  496.   word* T2 = tmp + 2*n;
  497.   int a_sign = absolute_cmp(A1,n,A0,n);
  498.   int b_sign = absolute_cmp(B0,n,B1,n);
  499.   Karatsuba(P0,A0,B0,T0,n/2);   // prod[0..2n]  := a0 * b0 
  500.   if (a_sign >= 0)
  501.      School_Sub(A1,n,A0,n,P2);  // prod[2n..3n] := a1 - a0
  502.   else 
  503.      School_Sub(A0,n,A1,n,P2);  // prod[2n..3n] := a0 - a1
  504.   if (b_sign >= 0)
  505.      School_Sub(B0,n,B1,n,P3);  // prod[3n..4n] := b0 - b1
  506.   else
  507.      School_Sub(B1,n,B0,n,P3);  // prod[3n..4n] := b1 - b0
  508.   Karatsuba(T2,P2,P3,T0,n/2);   // tmp[2n..4n]  := |a1-a0|*|b0-b1|
  509.   Karatsuba(P2,A1,B1,T0,n/2);   // prod[2n..4n] := a1 * b1
  510.   Copy_Vector(T0,P0,2*n);
  511.   /* now we have 
  512.                       P3      P2      P1      P0
  513.               +-------+-------+-------+-------+
  514.      prod =   |     a1*b1     |     a0*b0     |
  515.               +-------+-------+-------+-------+
  516.               
  517.                               T2      T1      T0
  518.               +-------+-------+-------+-------+
  519.       tmp =   ||a1-a0|*|b0-b1||     a0*b0     |
  520.               +-------+-------+-------+-------+
  521.   */
  522.   // add up partial products
  523.   School_Add(P1,3*n,P2,2*n,P1);   // prod[1n..3n] += prod[2n..4n]
  524.   School_Add(P1,3*n,T0,2*n,P1);   // prod[1n..3n] +=  tmp[0n..2n]
  525.   if (a_sign == b_sign)  
  526.     School_Add(P1,3*n,T2,2*n,P1); // prod[1n..3n] += tmp[2n..4n]
  527.   else
  528.     School_Sub(P1,3*n,T2,2*n,P1); // prod[1n..3n] -= tmp[2n..4n]
  529. }
  530. static sz_t Kara_Mult(word* a, sz_t a_used, word* b, sz_t b_used, word* prod)
  531.   // a_used >= b_used
  532.   if (b_used < 4*KARA_LIMIT)
  533.      return School_Mult(a, a_used, b, b_used, prod);
  534.   sz_t p_used = a_used + b_used;
  535.   int m = next_power(b_used)/KARA_LIMIT;
  536.   int n = 0;
  537.   while (n < b_used) n += m; // n = i*2^k with i < KARA_LIMIT
  538.   word* ap = a;
  539.   word* bp = b;
  540.   // extend length of b to n (append zeroes) 
  541.   if (n > b_used)
  542.   { bp = new word[n];
  543.     word* p = Copy_Vector(bp,b,b_used);
  544.     Init_Vector(p,n-b_used);
  545.    }
  546.   // partition a into t intervals of size n each
  547.   // r is size of remainder
  548.   int t = a_used / n;
  549.   int r = a_used % n;
  550.   if (r > n/2) // make length(a) a muliple of n
  551.   { t++;
  552.     r = 0;
  553.     ap  = new word[t*n];
  554.     word* p = Copy_Vector(ap,a,a_used);
  555.     Init_Vector(p,t*n-a_used);
  556.     a_used = t*n;
  557.    }
  558.   word* res = new word[a_used + n]; // result
  559.   Init_Vector(res,a_used+n);
  560.   word* tpr = new word[2*n];        // temporary product
  561.   word* tmp = new word[2*n];        // temporary space used by Karatsuba
  562.   word* q = ap;   // current position in ap
  563.   word* p = res;  // current position in result
  564.   while (t--)
  565.   { Karatsuba(tpr, q, bp, tmp, n/2);  // tpr := q[0..n-1] * bp[0..n-1]
  566.     School_Add(p,2*n,tpr,2*n,p);      // add tpr to result
  567.     q += n;
  568.     p += n;
  569.    }
  570.      
  571.   // use School_Mult to multiply rest of a with bp
  572.   while (r--) Mult_Inner_Loop(p++,bp,bp+b_used, *q++);
  573.   p = Copy_Vector(prod,res,p_used);  // copy result to pred
  574.   while (*--p == 0) p_used--;        // and adjust p_used
  575.   if (ap != a) delete[] ap;
  576.   if (bp != b) delete[] bp;
  577.   delete[] tmp;
  578.   delete[] res;
  579.   return p_used; 
  580. }
  581.   
  582. static word Shift_Left(word *a, word *b, sz_t length, sz_t shift)
  583.   // auxiliary function used in School_Div
  584.   // a := (b << shift) and return carry   (0 < shift < 32)
  585.   
  586.   word* b_stop = b + length;
  587.   if (shift == 0)
  588.   { while (b < b_stop) *a++ = *b++;
  589.     return 0;
  590.    }
  591.   int  r = WORD_LENGTH-shift;
  592.   word carry = 0;
  593.   while (b < b_stop)
  594.   { word B = *b++;
  595.     carry |= (B << shift);
  596.     *a++ = carry;
  597.     carry = (B >> r);
  598.    }
  599.   return carry; 
  600. }
  601. static sz_t School_Div(word* A, sz_t a_used, word* B, sz_t b_used,
  602.                         word* Q, word* R, sz_t* R_used)
  603. {
  604.   word* a      = new word[a_used + 1];
  605.   word* b      = new word[b_used];
  606.   word* b_stop = b + b_used;
  607.   sz_t quot_used = a_used - b_used + 1;
  608.   // we first normalize A and B, i.e. ...
  609.   sz_t shift = 0;
  610.   word sh = B[b_used-1];
  611.   while ((sh & 0x80000000) == 0)
  612.    { sh <<= 1;
  613.      shift++;
  614.    }
  615.   a[a_used] = Shift_Left(a, A, a_used, shift);
  616.   Shift_Left(b, B, b_used, shift);
  617.   // two often used values
  618.   word b1 = b[b_used-1];               
  619.   word b2 = (b_used > 1) ? b[b_used-2] : 0;
  620.   /* division main loop */
  621.   word* a_ptr = a + a_used;        // current position in a
  622.   word* Q_ptr = Q + quot_used - 1; // current position in Q
  623.  
  624.   while (Q_ptr >= Q)
  625.   {
  626.     word q = MAX_WORD;
  627.     if (*a_ptr != b1) 
  628.     { word r = DivTwoWordsByOne(*a_ptr, *(a_ptr-1), b1, &q);
  629.       word h11;
  630.       word h10 = Multiply_Words(q, b2, &h11);
  631.       word h21 = r;
  632.       word h20 = *(a_ptr-2);
  633.       while( h11 > h21 || (h11 == h21 && h10 > h20) ) // [h11,h10] > [h21,h20]
  634.       { q--;
  635.         if (h10 < b2) h11--;
  636.         h10 -= b2;
  637.         h21 += b1;
  638.         if (h21 < b1) break;
  639.        }
  640.      }
  641.      if (Div_Inner_Loop(a_ptr-b_used,b,b_stop,q)) // a -= b*q
  642.      { // if carry add one b back to a and decrement q  (never executed ?)
  643.        word* ap;
  644.        word* bp;
  645.        bool  carry = false;
  646.        for(bp = b, ap = a_ptr-b_used; bp < b_stop; bp++, ap++) 
  647.        { word aa = *ap;
  648.          word bb = *bp;
  649.          bb += aa;
  650.          if (carry)
  651.            { if (++bb > aa) carry = false; }
  652.          else
  653.              if (bb < aa) carry = true;
  654.          *ap = bb;
  655.         }
  656.        if (carry) (*ap)++; 
  657.        q--;
  658.      }
  659.     *Q_ptr-- = q;
  660.      a_ptr--;
  661.   }
  662.   
  663.   if (R)  // copy remainder to R[]
  664.   { word* p = a + b_used;
  665.     word* q = R + b_used;
  666.     // copy and shift a to R[]
  667.     if (shift) 
  668.       { int  r = WORD_LENGTH-shift;
  669.         word carry = 0;
  670.         while (p > a)
  671.         { word A = *--p;
  672.           carry |= (A >> shift);
  673.           *--q = carry;
  674.           carry = (A << r);
  675.          }
  676.        }
  677.     else
  678.        while (p > a) *--q = *--p;
  679.     for(q = R+b_used-1; b_used && *q==0; q--)  b_used--; 
  680.     *R_used = b_used;
  681.    }
  682.   delete[] a;
  683.   delete[] b;
  684.   if (Q[quot_used-1] == 0) quot_used--;
  685.   return quot_used;
  686. }
  687. static sz_t DivByOneWord(word *a, sz_t a_used, word B, word* quot, word* rem)
  688. {
  689.   word  r = 0;
  690.   word* a_ptr = a + a_used;
  691.   word* q_ptr = quot + a_used;
  692.   while (a_ptr > a) r = DivTwoWordsByOne(r,*--a_ptr,B,--q_ptr);
  693.   if (quot[a_used-1] == 0) a_used--;
  694.   if (rem) *rem = r;
  695.   return a_used;
  696. }
  697. //------------------------------------------------------------------------------
  698. // friend operators  + - * / % == < > ...
  699. //------------------------------------------------------------------------------
  700. integer operator+(const integer & a, const integer & b) 
  701. {
  702.   sz_t a_sign = a.PTR->sign;
  703.   sz_t b_sign = b.PTR->sign;
  704.   sz_t sum_size;
  705.   if (a_sign == ZERO) return b;
  706.   if (b_sign == ZERO) return a;
  707.   integer_rep* sum_ptr;
  708.   sz_t a_used = a.PTR->used;
  709.   sz_t b_used = b.PTR->used;
  710.   sz_t a_size = a.PTR->size;
  711.   sz_t b_size = b.PTR->size;
  712.   word* av = a.PTR->vec;
  713.   word* bv = b.PTR->vec;
  714.   // we distinguish the cases of equal and unequal sign
  715.   if (a_sign == b_sign)
  716.   { if (a_used >= b_used)
  717.      { sum_size = (a_used+1 <= a_size) ? a_size : 2*a_size;
  718.        sum_ptr = new_integer_rep(sum_size);
  719.        sum_ptr->used = School_Add(av, a_used, bv, b_used, sum_ptr->vec); 
  720.       }
  721.     else
  722.      { sum_size = (b_used+1 <= b_size) ? b_size : 2*b_size;
  723.        sum_ptr = new_integer_rep(sum_size);
  724.        sum_ptr->used = School_Add(bv, b_used, av, a_used, sum_ptr->vec); 
  725.       }
  726.     sum_ptr->sign = a_sign;
  727.     return sum_ptr;
  728.    }
  729. /* if |a| and |b| have different signs, we must subtract the smaller absolute
  730.  * value from the greater one and set the sign appropriately
  731.  */
  732.   int rel = a_used - b_used;
  733.   if (rel == 0)
  734.   { word* p = av + a_used;
  735.     word* q = bv + b_used;
  736.     while (a_used && *--p == *--q) 
  737.     { a_used--;
  738.       b_used--;
  739.      }
  740.     if (a_used == 0) return 0;
  741.     rel  = (*p > *q) ? 1 : -1;
  742.    }
  743.   if (rel > 0) 
  744.     { // |a| > |b|
  745.       sum_ptr = new_integer_rep(a_size);
  746.       sum_ptr->used = School_Sub(av, a_used, bv, b_used, sum_ptr->vec);
  747.       sum_ptr->sign = a_sign;
  748.      }
  749.   else
  750.     { // |a| < |b|
  751.       sum_ptr = new_integer_rep(b_size);
  752.       sum_ptr->used = School_Sub(bv, b_used, av, a_used, sum_ptr->vec);
  753.       sum_ptr->sign = b_sign;
  754.      }
  755.   return sum_ptr;
  756. }
  757. integer operator-(const integer & a, const integer & b)
  758. {
  759.   if (a.PTR == b.PTR) return 0;
  760.   sz_t a_sign = a.PTR->sign;
  761.   sz_t b_sign = b.PTR->sign;
  762.   sz_t a_used = a.PTR->used;
  763.   sz_t b_used = b.PTR->used;
  764.   sz_t a_size = a.PTR->size;
  765.   sz_t b_size = b.PTR->size;
  766.   word* av = a.PTR->vec;
  767.   word* bv = b.PTR->vec;
  768.   sz_t diff_size;
  769.   if (b_sign == ZERO) return a;
  770.   if (a_sign == ZERO) return -b;
  771.   integer_rep* diff_ptr;
  772.   /* we distinguish the cases of equal and unequal signs */
  773.   if (a_sign == b_sign)
  774.   { 
  775.     int rel = a_used - b_used;
  776.     if (rel == 0)
  777.     { word* p = av + a_used;
  778.       word* q = bv + b_used;
  779.       while (a_used && *--p == *--q) 
  780.       { a_used--;
  781.         b_used--;
  782.        }
  783.       if (a_used == 0) return 0;
  784.       rel  = (*p > *q) ? 1 : -1;
  785.      }
  786.     
  787.     if (rel > 0)
  788.     { // |a| > |b| 
  789.       diff_ptr = new_integer_rep(a_size);
  790.       diff_ptr->used = School_Sub(av, a_used, bv, b_used, diff_ptr->vec);
  791.       diff_ptr->sign = a_sign;  
  792.       return diff_ptr;
  793.      }
  794.     else 
  795.     {  // |b| > |a|
  796.       diff_ptr = new_integer_rep(b_size);
  797.       diff_ptr->used = School_Sub(bv, b_used, av, a_used, diff_ptr->vec);
  798.       diff_ptr->sign = -a_sign;
  799.       return diff_ptr;
  800.     }
  801.   }
  802. /*
  803.  * if |a| and |b| have different signs, we must carry out an addition and set
  804.  * the sign appropriately
  805.  */
  806.   if (a_used >= b_used)
  807.     { diff_size = (a_used+1 <= a_size) ? a_size : 2*a_size;
  808.       diff_ptr  = new_integer_rep(diff_size);
  809.       diff_ptr->used = School_Add(av, a_used, bv, b_used, diff_ptr->vec);
  810.      }
  811.   else
  812.     { diff_size = (b_used+1 <= b_size) ? b_size : 2*b_size;
  813.       diff_ptr  = new_integer_rep(diff_size);
  814.       diff_ptr->used = School_Add(bv, b_used, av, a_used, diff_ptr->vec);
  815.      }
  816.   diff_ptr->sign = a_sign;
  817.   return diff_ptr;
  818. }
  819. integer operator*(const integer& a, const integer& b) 
  820. {
  821.   sz_t a_sign = a.PTR->sign;
  822.   sz_t b_sign = b.PTR->sign;
  823.   if (a_sign == ZERO) return a;
  824.   if (b_sign == ZERO) return b;
  825.   sz_t a_used = a.PTR->used;
  826.   sz_t b_used = b.PTR->used;
  827.   integer_rep* prod_ptr;
  828.   if (a_used == 1 && b_used == 1)
  829.   { prod_ptr = new_integer_rep(2);
  830.     word* p  = prod_ptr->vec;
  831.     prod_ptr->sign = (a_sign == b_sign ? POSITIVE : NEGATIVE);
  832.     *p = Multiply_Words(a.PTR->vec[0], b.PTR->vec[0], p+1);
  833.     prod_ptr->used = (p[1]) ? 2 : 1;
  834.     return prod_ptr;
  835.    }
  836.   int sz = next_power(a_used+b_used);
  837.   prod_ptr = new_integer_rep(sz);
  838.   prod_ptr->sign = (a_sign == b_sign ? POSITIVE : NEGATIVE);
  839.   if (a_used >= b_used)
  840.       prod_ptr->used = Kara_Mult(a.PTR->vec, a_used, b.PTR->vec, b_used,
  841.                                  prod_ptr->vec);
  842.   else
  843.       prod_ptr->used = Kara_Mult(b.PTR->vec, b_used, a.PTR->vec, a_used,
  844.                                  prod_ptr->vec);
  845.   return prod_ptr;
  846. }
  847. integer operator/(const integer & a, const integer & b) 
  848.   sz_t a_sign = a.PTR->sign;
  849.   sz_t b_sign = b.PTR->sign;
  850.   sz_t a_used = a.PTR->used;
  851.   sz_t b_used = b.PTR->used;
  852.   if (b_sign == ZERO) error_handler(1,"division by zero");
  853.   if (a_sign == ZERO) return a;
  854.   int rel = absolute_cmp(a.PTR->vec,a_used, b.PTR->vec, b_used);
  855.   if (rel == 0) return (a_sign == b_sign) ? 1 : -1;  // |a| == |b|
  856.   if (rel  < 0) return 0;                            // |a| <  |b|
  857.   // |a| > |b|
  858.   int sz = next_power(a_used - b_used + 1);
  859.   integer_rep* quot_ptr = new_integer_rep(sz);
  860.   quot_ptr->sign = (a_sign == b_sign) ? POSITIVE : NEGATIVE;
  861.   if (b_used == 1) 
  862.       quot_ptr->used = DivByOneWord(a.PTR->vec, a_used, b.PTR->vec[0],
  863.                                     quot_ptr->vec,0);
  864.   else 
  865.       // |a| and |b| both have at least 2 digits
  866.       quot_ptr->used = School_Div(a.PTR->vec, a_used, b.PTR->vec, b_used,
  867.                                   quot_ptr->vec,0,0);
  868.   return quot_ptr;
  869. }
  870. integer operator%(const integer & a, const integer & b) 
  871.   sz_t a_sign = a.PTR->sign;
  872.   sz_t b_sign = b.PTR->sign;
  873.   sz_t a_used = a.PTR->used;
  874.   sz_t b_used = b.PTR->used;
  875.   if (b_sign == ZERO) error_handler(1,"mod by zero");
  876.   if (a_sign == ZERO) return a;
  877.   int rel = absolute_cmp(a.PTR->vec,a_used, b.PTR->vec, b_used);
  878.   if (rel == 0) return 0;  // |a| == |b|
  879.   if (rel  < 0) return a;  // |a| <  |b|
  880.   // |a| > |b|
  881.   int qsz = next_power(a_used - b_used + 1);
  882.   int rsz = b.PTR->size;
  883.   integer_rep* quot_ptr = new_integer_rep(qsz);
  884.   integer_rep* rem_ptr = new_integer_rep(rsz);
  885.   if (b_used == 1)
  886.     { quot_ptr->used = DivByOneWord(a.PTR->vec, a_used, b.PTR->vec[0],
  887.                                     quot_ptr->vec, rem_ptr->vec);
  888.       rem_ptr->used = (rem_ptr->vec[0] == 0) ? 0 : 1;
  889.      }
  890.   else 
  891.     { sz_t r_used;
  892.       School_Div(a.PTR->vec, a_used, b.PTR->vec, b_used,
  893.                  quot_ptr->vec,rem_ptr->vec,&r_used);
  894.       rem_ptr->used = r_used;
  895.      }
  896.   delete_integer_rep(quot_ptr);
  897.   if (rem_ptr->used == 0) 
  898.      rem_ptr->sign = ZERO;
  899.   else
  900.      rem_ptr->sign = a_sign;
  901.   return rem_ptr;
  902. }
  903. integer operator & (const integer & a, const integer & b)   // bitwise and
  904. {
  905.   sz_t a_sign = a.PTR->sign;
  906.   sz_t b_sign = b.PTR->sign;
  907.   if (a_sign == 0) return a;
  908.   if (b_sign == 0) return b;
  909.   sz_t a_used = a.PTR->used;
  910.   sz_t b_used = b.PTR->used;
  911.   integer_rep* and_ptr;
  912.   word* ap = a.PTR->vec;
  913.   word* bp = b.PTR->vec;
  914.   word* a_stop = ap + a_used; 
  915.   word* b_stop = bp + b_used; 
  916.   int used;
  917.   word* p;
  918.   if (a_used <= b_used)
  919.      { and_ptr = new_integer_rep(a.PTR->size);
  920.        used = a_used;
  921.        p = and_ptr->vec;
  922.        while (ap < a_stop) *p++ = *ap++ & *bp++;
  923.      }
  924.   else
  925.      { and_ptr = new_integer_rep(b.PTR->size);
  926.        used = b_used;
  927.        p = and_ptr->vec;
  928.        while (bp < b_stop) *p++ = *ap++ & *bp++;
  929.       }
  930.   while (*--p == 0 && used > 0) used--;
  931.   and_ptr->used = used;
  932.   and_ptr->sign = (used > 0) ? a_sign : ZERO;
  933.   return and_ptr;
  934. }
  935.  
  936. integer operator | (const integer & a, const integer & b)   // bitwise or
  937. {
  938.   sz_t a_sign = a.PTR->sign;
  939.   sz_t b_sign = b.PTR->sign;
  940.   if (a_sign == 0) return a;
  941.   if (b_sign == 0) return b;
  942.   sz_t a_used = a.PTR->used;
  943.   sz_t b_used = b.PTR->used;
  944.   integer_rep* and_ptr;
  945.   word* ap = a.PTR->vec;
  946.   word* bp = b.PTR->vec;
  947.   word* a_stop = ap + a_used; 
  948.   word* b_stop = bp + b_used; 
  949.   if (a_used >= b_used)
  950.      { and_ptr = new_integer_rep(a.PTR->size);
  951.        and_ptr->used = a_used;
  952.        and_ptr->sign = a_sign;
  953.        word* p = and_ptr->vec;
  954.        while (bp < b_stop) *p++ = *ap++ | *bp++;
  955.        while (ap < a_stop) *p++ = *ap++;
  956.      }
  957.   else
  958.      { and_ptr = new_integer_rep(b.PTR->size);
  959.        and_ptr->used = b_used;
  960.        and_ptr->sign = a_sign;
  961.        word* p = and_ptr->vec;
  962.        while (ap < a_stop) *p++ = *ap++ | *bp++;
  963.        while (bp < b_stop) *p++ = *bp++;
  964.       }
  965.   and_ptr->sign = a_sign;
  966.   return and_ptr;
  967. }
  968.  
  969. bool operator > (const integer & a, const integer & b)
  970. {
  971.   if (a.PTR == b.PTR) return false;
  972.   int a_sign = a.PTR->sign;
  973.   int b_sign = b.PTR->sign;
  974.   if (a_sign > b_sign) return true;
  975.   if (a_sign < b_sign) return false;
  976.   /* the signs are equal */
  977.   if (a_sign == ZERO) return false;
  978.   if (a_sign == POSITIVE)
  979.     return (absolute_cmp(a.PTR->vec,a.PTR->used,
  980.                          b.PTR->vec,b.PTR->used) > 0);
  981.   else
  982.     return (absolute_cmp(a.PTR->vec,a.PTR->used,
  983.                          b.PTR->vec,b.PTR->used) < 0);
  984. }
  985. bool operator < (const integer & a, const integer & b)
  986. {
  987.   if (a.PTR == b.PTR) return false;
  988.   int a_sign = a.PTR->sign;
  989.   int b_sign = b.PTR->sign;
  990.   if (a_sign < b_sign) return true;
  991.   if (a_sign > b_sign) return false;
  992.   /* the signs are equal */
  993.   if (a_sign == ZERO) return false;
  994.   if (a_sign == POSITIVE)
  995.     return (absolute_cmp(a.PTR->vec,a.PTR->used,
  996.                          b.PTR->vec,b.PTR->used) < 0);
  997.   else
  998.     return (absolute_cmp(a.PTR->vec,a.PTR->used,
  999.                          b.PTR->vec,b.PTR->used) > 0);
  1000. }
  1001. bool operator == (const integer & a, const integer & b)
  1002. {
  1003.   if (a.PTR == b.PTR) return true;
  1004.   int a_sign = a.PTR->sign;
  1005.   int b_sign = b.PTR->sign;
  1006.   if (a_sign != b_sign) return false;
  1007.   if (a_sign == ZERO) return true;
  1008.   return (absolute_cmp(a.PTR->vec,a.PTR->used,
  1009.                        b.PTR->vec,b.PTR->used) == 0);
  1010. }
  1011. integer gcd(const integer& a, const integer& b)
  1012.   // gcd is not efficient. See Knuth 2 for improvements. 
  1013.   int a_sign = a.PTR->sign;
  1014.   int b_sign = b.PTR->sign;
  1015.   
  1016.   if (a_sign == ZERO)
  1017.     if (b_sign == ZERO)
  1018.         return 1;
  1019.     else
  1020.         return abs(b);
  1021.   // a is non-zero
  1022.   if (b_sign == 0) return abs(a);
  1023.   
  1024.   // both a and b are non-zero
  1025.   integer u = abs(a);
  1026.   integer v = abs(b);
  1027.   if (u < v) v = v%u;
  1028.    
  1029.   while (sign(v) != 0)
  1030.   { integer tmp = u % v; 
  1031.     u = v;
  1032.     v = tmp;
  1033.    }
  1034.   return u;
  1035. }
  1036. //------------------------------------------------------------------------------
  1037. // member functions
  1038. //------------------------------------------------------------------------------
  1039. void integer::absolute() // *this = abs(*this), nur effizienter
  1040. {
  1041.   if (PTR->count == 1) PTR->sign = POSITIVE;
  1042.   else 
  1043.     *this = abs(*this); 
  1044. }
  1045. int integer::zeros() const
  1046. { // gives the number of zeros at the end of the integer
  1047.   if (PTR->sign == ZERO) return 0;
  1048.   int k=0;
  1049.   while (!(PTR->vec[k])) k++;
  1050.   int len = k * WORD_LENGTH;
  1051.   word low = PTR->vec[k];
  1052.   if (! (low & 65535)) { low >>= 16; len += 16; }
  1053.   if (! (low & 255))  { low >>= 8; len += 8; }
  1054.   if (! (low & 15))  { low >>= 4; len += 4; }
  1055.   if (! (low & 3))  { low >>= 2; len += 2; }
  1056.   if (! (low & 1))  { low >>= 1; len += 1; }
  1057.   return len;
  1058. }
  1059. integer integer::div(const integer & b, integer& r) 
  1060.   // returns quotient and assings remainder to r
  1061.   sz_t a_sign = PTR->sign;
  1062.   sz_t b_sign = b.PTR->sign;
  1063.   sz_t a_used = PTR->used;
  1064.   sz_t b_used = b.PTR->used;
  1065.   if (b_sign == ZERO) error_handler(1,"division by zero");
  1066.   if (a_sign == ZERO) 
  1067.   { r = 0;
  1068.     return *this;
  1069.    }
  1070.   int rel = absolute_cmp(PTR->vec,a_used, b.PTR->vec, b_used);
  1071.   if (rel == 0) 
  1072.   { r = 0;
  1073.     return (a_sign == b_sign) ? 1 : -1; 
  1074.    }
  1075.   if (rel  < 0) 
  1076.   { r = *this;
  1077.     return 0;                     
  1078.    }
  1079.   // |a| > |b|
  1080.   int sz = next_power(a_used - b_used + 1);
  1081.   integer_rep* quot_ptr = new_integer_rep(sz);
  1082.   quot_ptr->sign = (a_sign == b_sign) ? POSITIVE : NEGATIVE;
  1083.   integer_rep* rem_ptr = new_integer_rep(b.PTR->size);
  1084.   sz_t r_used;
  1085.   if (b_used == 1)
  1086.     { quot_ptr->used = DivByOneWord(PTR->vec, a_used, b.PTR->vec[0],
  1087.                                     quot_ptr->vec, rem_ptr->vec);
  1088.       r_used = (rem_ptr->vec[0] == 0) ? 0 : 1;
  1089.      }
  1090.   else 
  1091.      School_Div(PTR->vec, a_used, b.PTR->vec, b_used,
  1092.                 quot_ptr->vec,rem_ptr->vec,&r_used);
  1093.   rem_ptr->used = r_used;
  1094.   rem_ptr->sign = (r_used == 0) ? ZERO : a_sign;
  1095.   r = rem_ptr;
  1096.   return quot_ptr;
  1097. }
  1098. int integer::length()  const   // number of bits
  1099. { if (PTR->sign == ZERO) return 0;
  1100.   int len = PTR->used - 1;
  1101.   word hi= PTR->vec[len];
  1102.   len *= WORD_LENGTH;
  1103.   while(hi)
  1104.   { hi >>= 1;
  1105.     len++;
  1106.    }
  1107.   return len;
  1108.  }
  1109.   
  1110. integer integer::operator-()  const
  1111. { // unary minus
  1112.   if (PTR->sign == ZERO) return *this;
  1113.   integer_rep* p = copy_integer_rep(PTR);
  1114.   p->sign = -PTR->sign;
  1115.   return p;
  1116. }
  1117. integer integer::operator~()  const
  1118. { // negation
  1119.   integer_rep* p = copy_integer_rep(PTR);
  1120.   word* wp = p->vec + p->used;
  1121.   while (--wp >= p->vec) *wp = ~*wp;
  1122.   return p;
  1123. }
  1124. bool integer::operator==(int l) const
  1125. { int sig = PTR->sign;
  1126.   if (l==0) return sig == ZERO;
  1127.   if (PTR->used > 1) return false;
  1128.   if (l > 0 )
  1129.   { if (sig <= 0) return false;
  1130.     return PTR->vec[0] == word(l);
  1131.    }
  1132.   // l < 0
  1133.   if (sig >= 0) return false;
  1134.   return PTR->vec[0] == word(-l);
  1135. }
  1136. bool integer::operator<(int l) const
  1137. { int sig = PTR->sign;
  1138.   if (l==0) return sig == NEGATIVE;
  1139.   if (l > 0 )
  1140.   { if (sig <= 0) return true;
  1141.     if (PTR->used > 1) return false;
  1142.     return PTR->vec[0] < word(l);
  1143.    }
  1144.   
  1145.   // l < 0
  1146.   if (sig >= 0) return false;
  1147.   if (PTR->used > 1) return true;
  1148.   return PTR->vec[0] > word(-l);
  1149. }
  1150. bool integer::operator>(int l) const
  1151. { int sig = PTR->sign;
  1152.   if (l==0) return sig == POSITIVE;
  1153.   if (l < 0 )
  1154.   { if (sig >= 0) return true;
  1155.     if (PTR->used > 1) return false;
  1156.     return PTR->vec[0] < word(-l);
  1157.    }
  1158.   
  1159.   // l > 0
  1160.   if (sig <= 0) return false;
  1161.   if (PTR->used > 1) return true;
  1162.   return PTR->vec[0] > word(l);
  1163. }
  1164. double integer::todouble() const
  1165.   int i = PTR->used;
  1166.   if (i == 0) return 0;
  1167.   if (i > 32) return 2*MAXDOUBLE; //Infinity
  1168.   word*  v = PTR->vec;
  1169.   double d = 0;
  1170.   while (i > 0) d = pow32*d + v[--i];
  1171.   return (PTR->sign == NEGATIVE) ? -d : d;
  1172. }
  1173. integer integer::sqrt() const
  1174. {
  1175.   if (PTR->sign == NEGATIVE)
  1176.     error_handler(1, "negative argument in integer::sqrt");
  1177.   if (PTR->sign == ZERO) return *this;
  1178.   integer root = (*this) >> (length()/2);  // first approx.
  1179.   integer fix  = (root*root + *this)/(root << 1);
  1180.   while (fix != root)
  1181.   { fix  = (root*root + *this)/(root << 1);
  1182.     root = (fix*fix   + *this)/(fix << 1);
  1183.   }
  1184.   return root;  
  1185. }
  1186. integer integer::operator<<(long n)  const
  1187. {
  1188.   if (PTR->sign == ZERO || n == 0) return *this;
  1189.   int w_shift = int(n / WORD_LENGTH);
  1190.   int b_shift = int(n % WORD_LENGTH);
  1191.   int used = PTR->used + w_shift;
  1192.   int r = WORD_LENGTH - b_shift;
  1193.   if (b_shift && (PTR->vec[PTR->used-1] >> r)) used++;
  1194.   int sz = next_power(used);
  1195.   integer_rep* result;
  1196.   result = new_integer_rep(sz);
  1197.   result->used = used;
  1198.   result->sign = PTR->sign;
  1199.   word* q = PTR->vec;
  1200.   word* q_stop = q + PTR->used;
  1201.   word* p = result->vec;
  1202.   while (w_shift--) *p++ = 0;
  1203.   if (b_shift) 
  1204.     { word carry = 0;
  1205.       while (q < q_stop)
  1206.       { word B = *q++;
  1207.         carry |= (B << b_shift);
  1208.         *p++ = carry;
  1209.         carry = (B >> r);
  1210.        }
  1211.       if (carry) *p = carry;
  1212.      }
  1213.   else
  1214.      while (q < q_stop) *p++ = *q++;
  1215.   return result;
  1216. }
  1217. integer integer::operator>>(long n)  const
  1218. {
  1219.   if (n <= 0 || PTR->sign == ZERO) return *this;
  1220.   int sticks = int(n / WORD_LENGTH);
  1221.   int shifts = int(n % WORD_LENGTH);
  1222.   int used   = PTR->used - sticks;
  1223.  
  1224.   int sz = next_power(used);
  1225.  
  1226.   integer_rep* result;
  1227.  
  1228.   result = new_integer_rep(sz);
  1229.   result->sign = PTR->sign;
  1230.  
  1231.   word* p = result->vec + used;
  1232.   word* q = PTR->vec + PTR->used;
  1233.  
  1234.   if (shifts != 0)
  1235.     { word carry = 0;
  1236.       int r = WORD_LENGTH - shifts;
  1237.       while (p > result->vec)
  1238.       { word B = *--q;
  1239.         carry |= (B >> shifts);
  1240.         *--p = carry;
  1241.         carry = (B << r);
  1242.        }
  1243.      }
  1244.   else
  1245.      while (p > result->vec) *--p = *--q;
  1246.  
  1247.   if (result->vec[used-1] == 0) used--;
  1248.   if (used == 0) result->sign = ZERO;
  1249.  
  1250.   result->used = used;
  1251.  
  1252.   return result;
  1253. }
  1254.  
  1255. //------------------------------------------------------------------------------
  1256. // stream i/o
  1257. //------------------------------------------------------------------------------
  1258. void integer::hex_print(ostream& out)
  1259. { if (PTR->sign == ZERO)
  1260.   { out << "0";
  1261.     return;
  1262.    }
  1263.   word* p = PTR->vec + PTR->used;
  1264.   out << string("%x",*--p);
  1265.   while (p > PTR->vec) out << string("%0x",*--p);
  1266. }
  1267. ostream & operator << (ostream & out, const integer & x) 
  1268. {
  1269.   if (x.PTR->sign == ZERO) 
  1270.   { out << "0";
  1271.     return out;
  1272.    }
  1273.   if (x.PTR->sign == NEGATIVE) out << "-";
  1274.   Print_Vector(x.PTR->vec,x.PTR->used,out);
  1275.   return out;
  1276. }
  1277. istream & operator >> (istream & in, integer & a) 
  1278. {
  1279.   bool negative = false;
  1280.   const int null = '0';
  1281.   char c;
  1282.   while (in.get(c) && isspace(c));
  1283.   if (c == '-') 
  1284.   { negative = true;
  1285.     while (in.get(c) && isspace(c));
  1286.    }
  1287.   if (isdigit(c)) 
  1288.   { a = c - '0';
  1289.     while (in.get(c) && isdigit(c)) a = 10*a + (c-null);
  1290.    }
  1291.   if (sign(a) != 0 && negative) a = -a;
  1292.   return in;
  1293. }
  1294. //------------------------------------------------------------------------------
  1295. // miscellaneous 
  1296. //------------------------------------------------------------------------------
  1297. integer_rep* copy_integer_rep(integer_rep* x)
  1298. { integer_rep* result = new_integer_rep(x->size);
  1299.   result->sign = x->sign;
  1300.   result->used = x->used;
  1301.   Copy_Vector(result->vec,x->vec,x->size);
  1302.   return result;
  1303. }
  1304. integer abs(const integer & a)
  1305. { if (a.PTR->sign >= 0) return a;
  1306.          integer_rep* ptr = copy_integer_rep(a.PTR);
  1307.          ptr->sign = POSITIVE;
  1308.          return ptr;
  1309. }
  1310. int log(const integer & a)
  1311. {
  1312.   if (a.PTR->sign != POSITIVE)
  1313.         error_handler(999,"domain error in log(integer)");
  1314.   int l  = a.PTR->used - 1;
  1315.   int lg = l * WORD_LENGTH;
  1316.   word hi = a.PTR->vec[l];
  1317.   while (hi >>= 1) lg++;
  1318.   return lg;
  1319. }
  1320. int integer::cmp(const integer & a, const integer & b)
  1321. { int a_sign = a.PTR->sign;
  1322.   int b_sign = b.PTR->sign;
  1323.   if (a_sign < b_sign) return -1;
  1324.   if (a_sign > b_sign) return  1;
  1325.   // the signs are equal 
  1326.   if (a_sign == ZERO) return 0;
  1327.   if (a_sign == POSITIVE)
  1328.       return  absolute_cmp(a.PTR->vec,a.PTR->used,
  1329.                            b.PTR->vec,b.PTR->used);
  1330.   else
  1331.       return -absolute_cmp(a.PTR->vec,a.PTR->used,
  1332.                            b.PTR->vec,b.PTR->used);
  1333. }
  1334. integer integer::random(int n)  // return n-bit random integer
  1335.   sz_t w = n / WORD_LENGTH;
  1336.   sz_t r = n % WORD_LENGTH;
  1337.   if (r) w++;
  1338.   int sz = next_power(w);
  1339.   integer_rep* ptr = new_integer_rep(sz);
  1340.   ptr->sign = POSITIVE;
  1341.   ptr->used = w;
  1342.   for (int i = 0; i < w; i++) rand_int >> ptr->vec[i];
  1343.   if (r) ptr->vec[w-1] >>= (WORD_LENGTH-r);
  1344.   return ptr;
  1345.  }