home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / OPENSTEP / UNIX / GNU / gcc-2.7.2.3.1-I / lib / g++-include / Integer.h < prev    next >
Encoding:
C/C++ Source or Header  |  1997-09-12  |  27.4 KB  |  1,135 lines

  1. // This may look like C code, but it is really -*- C++ -*-
  2.  
  3. /* 
  4. Copyright (C) 1988 Free Software Foundation
  5.     written by Doug Lea (dl@rocky.oswego.edu)
  6.  
  7. This file is part of the GNU C++ Library.  This library is free
  8. software; you can redistribute it and/or modify it under the terms of
  9. the GNU Library General Public License as published by the Free
  10. Software Foundation; either version 2 of the License, or (at your
  11. option) any later version.  This library is distributed in the hope
  12. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  13. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  14. PURPOSE.  See the GNU Library General Public License for more details.
  15. You should have received a copy of the GNU Library General Public
  16. License along with this library; if not, write to the Free Software
  17. Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. */
  19.  
  20. #ifndef _Integer_h
  21. #ifdef __GNUG__
  22. #pragma interface
  23. #endif
  24. #define _Integer_h 1
  25.  
  26. #include <iostream.h>
  27.  
  28. #undef OK
  29.  
  30. struct IntRep                    // internal Integer representations
  31. {
  32.   unsigned short  len;          // current length
  33.   unsigned short  sz;           // allocated space (0 means static).
  34.   short           sgn;          // 1 means >= 0; 0 means < 0 
  35.   unsigned short  s[1];         // represented as ushort array starting here
  36. };
  37.  
  38. // True if REP is staticly (or manually) allocated,
  39. // and should not be deleted by an Integer destructor.
  40. #define STATIC_IntRep(rep) ((rep)->sz==0)
  41.  
  42. extern IntRep*  Ialloc(IntRep*, const unsigned short *, int, int, int);
  43. extern IntRep*  Icalloc(IntRep*, int);
  44. extern IntRep*  Icopy_ulong(IntRep*, unsigned long);
  45. extern IntRep*  Icopy_long(IntRep*, long);
  46. extern IntRep*  Icopy(IntRep*, const IntRep*);
  47. extern IntRep*  Iresize(IntRep*, int);
  48. extern IntRep*  add(const IntRep*, int, const IntRep*, int, IntRep*);
  49. extern IntRep*  add(const IntRep*, int, long, IntRep*);
  50. extern IntRep*  multiply(const IntRep*, const IntRep*, IntRep*);
  51. extern IntRep*  multiply(const IntRep*, long, IntRep*);
  52. extern IntRep*  lshift(const IntRep*, long, IntRep*);
  53. extern IntRep*  lshift(const IntRep*, const IntRep*, int, IntRep*);
  54. extern IntRep*  bitop(const IntRep*, const IntRep*, IntRep*, char);
  55. extern IntRep*  bitop(const IntRep*, long, IntRep*, char);
  56. extern IntRep*  power(const IntRep*, long, IntRep*);
  57. extern IntRep*  div(const IntRep*, const IntRep*, IntRep*);
  58. extern IntRep*  mod(const IntRep*, const IntRep*, IntRep*);
  59. extern IntRep*  div(const IntRep*, long, IntRep*);
  60. extern IntRep*  mod(const IntRep*, long, IntRep*);
  61. extern IntRep*  compl(const IntRep*, IntRep*);
  62. extern IntRep*  abs(const IntRep*, IntRep*);
  63. extern IntRep*  negate(const IntRep*, IntRep*);
  64. extern IntRep*  pow(const IntRep*, long);
  65. extern IntRep*  gcd(const IntRep*, const IntRep* y);
  66. extern int      compare(const IntRep*, const IntRep*);
  67. extern int      compare(const IntRep*, long);
  68. extern int      ucompare(const IntRep*, const IntRep*);
  69. extern int      ucompare(const IntRep*, long);
  70. extern char*    Itoa(const IntRep* x, int base = 10, int width = 0);
  71. extern char*    cvtItoa(const IntRep* x, char* fmt, int& fmtlen, int base,
  72.                         int showbase, int width, int align_right, 
  73.                         char fillchar, char Xcase, int showpos);
  74. extern IntRep*  atoIntRep(const char* s, int base = 10);
  75. extern long     Itolong(const IntRep*);
  76. extern int      Iislong(const IntRep*);
  77. extern long     lg(const IntRep*);
  78.  
  79. extern IntRep _ZeroRep, _OneRep, _MinusOneRep;
  80.  
  81. class Integer
  82. {
  83. protected:
  84.   IntRep*         rep;
  85. public:
  86.                   Integer();
  87.                   Integer(int);
  88.                   Integer(long);
  89.                   Integer(unsigned long);
  90.                   Integer(IntRep*);
  91.                   Integer(const Integer&);
  92.  
  93.                   ~Integer();
  94.   Integer&        operator =  (const Integer&);
  95.   Integer&        operator =  (long);
  96.  
  97. // unary operations to self
  98.  
  99.   Integer&        operator ++ ();
  100.   Integer&        operator -- ();
  101.   void            negate();          // negate in-place
  102.   void            abs();             // absolute-value in-place
  103.   void            complement();      // bitwise complement in-place
  104.  
  105. // assignment-based operations
  106.  
  107.   Integer&        operator += (const Integer&);
  108.   Integer&        operator -= (const Integer&);
  109.   Integer&        operator *= (const Integer&);
  110.   Integer&        operator /= (const Integer&);
  111.   Integer&        operator %= (const Integer&);
  112.   Integer&        operator <<=(const Integer&);
  113.   Integer&        operator >>=(const Integer&);
  114.   Integer&        operator &= (const Integer&);
  115.   Integer&        operator |= (const Integer&);
  116.   Integer&        operator ^= (const Integer&);
  117.  
  118.   Integer&        operator += (long);
  119.   Integer&        operator -= (long);
  120.   Integer&        operator *= (long);
  121.   Integer&        operator /= (long);
  122.   Integer&        operator %= (long);
  123.   Integer&        operator <<=(long);
  124.   Integer&        operator >>=(long);
  125.   Integer&        operator &= (long);
  126.   Integer&        operator |= (long);
  127.   Integer&        operator ^= (long);
  128.  
  129. // (constructive binary operations are inlined below)
  130.  
  131. #if defined (__GNUG__) && ! defined (__STRICT_ANSI__)
  132.   friend Integer operator <? (const Integer& x, const Integer& y); // min
  133.   friend Integer operator >? (const Integer& x, const Integer& y); // max
  134. #endif
  135.  
  136. // builtin Integer functions that must be friends
  137.  
  138.   friend long     lg (const Integer&); // floor log base 2 of abs(x)
  139.   friend double   ratio(const Integer& x, const Integer& y);
  140.                   // return x/y as a double
  141.  
  142.   friend Integer  gcd(const Integer&, const Integer&);
  143.   friend int      even(const Integer&); // true if even
  144.   friend int      odd(const Integer&); // true if odd
  145.   friend int      sign(const Integer&); // returns -1, 0, +1
  146.  
  147.   friend void     (setbit)(Integer& x, long b);   // set b'th bit of x
  148.   friend void     clearbit(Integer& x, long b); // clear b'th bit
  149.   friend int      testbit(const Integer& x, long b);  // return b'th bit
  150.  
  151. // procedural versions of operators
  152.  
  153.   friend void     abs(const Integer& x, Integer& dest);
  154.   friend void     negate(const Integer& x, Integer& dest);
  155.   friend void     complement(const Integer& x, Integer& dest);
  156.  
  157.   friend int      compare(const Integer&, const Integer&);  
  158.   friend int      ucompare(const Integer&, const Integer&); 
  159.   friend void     add(const Integer& x, const Integer& y, Integer& dest);
  160.   friend void     sub(const Integer& x, const Integer& y, Integer& dest);
  161.   friend void     mul(const Integer& x, const Integer& y, Integer& dest);
  162.   friend void     div(const Integer& x, const Integer& y, Integer& dest);
  163.   friend void     mod(const Integer& x, const Integer& y, Integer& dest);
  164.   friend void     divide(const Integer& x, const Integer& y, 
  165.                          Integer& q, Integer& r);
  166. #ifndef __STRICT_ANSI__
  167.   friend void     and(const Integer& x, const Integer& y, Integer& dest);
  168.   friend void     or(const Integer& x, const Integer& y, Integer& dest);
  169.   friend void     xor(const Integer& x, const Integer& y, Integer& dest); 
  170. #endif
  171.   friend void     lshift(const Integer& x, const Integer& y, Integer& dest);
  172.   friend void     rshift(const Integer& x, const Integer& y, Integer& dest);
  173.   friend void     pow(const Integer& x, const Integer& y, Integer& dest);
  174.  
  175.   friend int      compare(const Integer&, long);  
  176.   friend int      ucompare(const Integer&, long); 
  177.   friend void     add(const Integer& x, long y, Integer& dest);
  178.   friend void     sub(const Integer& x, long y, Integer& dest);
  179.   friend void     mul(const Integer& x, long y, Integer& dest);
  180.   friend void     div(const Integer& x, long y, Integer& dest);
  181.   friend void     mod(const Integer& x, long y, Integer& dest);
  182.   friend void     divide(const Integer& x, long y, Integer& q, long& r);
  183. #ifndef __STRICT_ANSI__
  184.   friend void     and(const Integer& x, long y, Integer& dest);
  185.   friend void     or(const Integer& x, long y, Integer& dest);
  186.   friend void     xor(const Integer& x, long y, Integer& dest);
  187. #endif
  188.   friend void     lshift(const Integer& x, long y, Integer& dest);
  189.   friend void     rshift(const Integer& x, long y, Integer& dest);
  190.   friend void     pow(const Integer& x, long y, Integer& dest);
  191.  
  192.   friend int      compare(long, const Integer&);  
  193.   friend int      ucompare(long, const Integer&); 
  194.   friend void     add(long x, const Integer& y, Integer& dest);
  195.   friend void     sub(long x, const Integer& y, Integer& dest);
  196.   friend void     mul(long x, const Integer& y, Integer& dest);
  197. #ifndef __STRICT_ANSI__
  198.   friend void     and(long x, const Integer& y, Integer& dest);
  199.   friend void     or(long x, const Integer& y, Integer& dest);
  200.   friend void     xor(long x, const Integer& y, Integer& dest);
  201. #endif
  202.  
  203.   friend Integer  operator &  (const Integer&, const Integer&);
  204.   friend Integer  operator &  (const Integer&, long);
  205.   friend Integer  operator &  (long, const Integer&);
  206.   friend Integer  operator |  (const Integer&, const Integer&);
  207.   friend Integer  operator |  (const Integer&, long);
  208.   friend Integer  operator |  (long, const Integer&);
  209.   friend Integer  operator ^  (const Integer&, const Integer&);
  210.   friend Integer  operator ^  (const Integer&, long);
  211.   friend Integer  operator ^  (long, const Integer&);
  212.  
  213. // coercion & conversion
  214.  
  215.   int             fits_in_long() const { return Iislong(rep); }
  216.   int             fits_in_double() const;
  217.  
  218.   long          as_long() const { return Itolong(rep); }
  219.   double      as_double() const;
  220.  
  221.   friend char*    Itoa(const Integer& x, int base = 10, int width = 0);
  222.   friend Integer  atoI(const char* s, int base = 10);
  223.   void          printon(ostream& s, int base = 10, int width = 0) const;
  224.   
  225.   friend istream& operator >> (istream& s, Integer& y);
  226.   friend ostream& operator << (ostream& s, const Integer& y);
  227.  
  228. // error detection
  229.  
  230.   int             initialized() const;
  231.   void   error(const char* msg) const;
  232.   int             OK() const;  
  233. };
  234.  
  235.  
  236. //  (These are declared inline)
  237.  
  238.   int      operator == (const Integer&, const Integer&);
  239.   int      operator == (const Integer&, long);
  240.   int      operator != (const Integer&, const Integer&);
  241.   int      operator != (const Integer&, long);
  242.   int      operator <  (const Integer&, const Integer&);
  243.   int      operator <  (const Integer&, long);
  244.   int      operator <= (const Integer&, const Integer&);
  245.   int      operator <= (const Integer&, long);
  246.   int      operator >  (const Integer&, const Integer&);
  247.   int      operator >  (const Integer&, long);
  248.   int      operator >= (const Integer&, const Integer&);
  249.   int      operator >= (const Integer&, long);
  250.   Integer  operator -  (const Integer&);
  251.   Integer  operator ~  (const Integer&);
  252.   Integer  operator +  (const Integer&, const Integer&);
  253.   Integer  operator +  (const Integer&, long);
  254.   Integer  operator +  (long, const Integer&);
  255.   Integer  operator -  (const Integer&, const Integer&);
  256.   Integer  operator -  (const Integer&, long);
  257.   Integer  operator -  (long, const Integer&);
  258.   Integer  operator *  (const Integer&, const Integer&);
  259.   Integer  operator *  (const Integer&, long);
  260.   Integer  operator *  (long, const Integer&);
  261.   Integer  operator /  (const Integer&, const Integer&);
  262.   Integer  operator /  (const Integer&, long);
  263.   Integer  operator %  (const Integer&, const Integer&);
  264.   Integer  operator %  (const Integer&, long);
  265.   Integer  operator << (const Integer&, const Integer&);
  266.   Integer  operator << (const Integer&, long);
  267.   Integer  operator >> (const Integer&, const Integer&);
  268.   Integer  operator >> (const Integer&, long);
  269.  
  270.   Integer  abs(const Integer&); // absolute value
  271.   Integer  sqr(const Integer&); // square
  272.  
  273.   Integer  pow(const Integer& x, const Integer& y);
  274.   Integer  pow(const Integer& x, long y);
  275.   Integer  Ipow(long x, long y); // x to the y as Integer 
  276.  
  277.  
  278. extern char*    dec(const Integer& x, int width = 0);
  279. extern char*    oct(const Integer& x, int width = 0);
  280. extern char*    hex(const Integer& x, int width = 0);
  281. extern Integer  sqrt(const Integer&); // floor of square root
  282. extern Integer  lcm(const Integer& x, const Integer& y); // least common mult
  283.  
  284.  
  285. typedef Integer IntTmp; // for backward compatibility
  286.  
  287. inline Integer::Integer() :rep(&_ZeroRep) {}
  288.  
  289. inline Integer::Integer(IntRep* r) :rep(r) {}
  290.  
  291. inline Integer::Integer(int y) :rep(Icopy_long(0, (long)y)) {}
  292.  
  293. inline Integer::Integer(long y) :rep(Icopy_long(0, y)) {}
  294.  
  295. inline Integer::Integer(unsigned long y) :rep(Icopy_ulong(0, y)) {}
  296.  
  297. inline Integer::Integer(const Integer&  y) :rep(Icopy(0, y.rep)) {}
  298.  
  299. inline Integer::~Integer() { if (rep && !STATIC_IntRep(rep)) delete rep; }
  300.  
  301. inline Integer&  Integer::operator = (const Integer&  y)
  302. {
  303.   rep = Icopy(rep, y.rep);
  304.   return *this;
  305. }
  306.  
  307. inline Integer& Integer::operator = (long y)
  308. {
  309.   rep = Icopy_long(rep, y);
  310.   return *this;
  311. }
  312.  
  313. inline int Integer::initialized() const
  314. {
  315.   return rep != 0;
  316. }
  317.  
  318. // procedural versions
  319.  
  320. inline int compare(const Integer& x, const Integer& y)
  321. {
  322.   return compare(x.rep, y.rep);
  323. }
  324.  
  325. inline int ucompare(const Integer& x, const Integer& y)
  326. {
  327.   return ucompare(x.rep, y.rep);
  328. }
  329.  
  330. inline int compare(const Integer& x, long y)
  331. {
  332.   return compare(x.rep, y);
  333. }
  334.  
  335. inline int ucompare(const Integer& x, long y)
  336. {
  337.   return ucompare(x.rep, y);
  338. }
  339.  
  340. inline int compare(long x, const Integer& y)
  341. {
  342.   return -compare(y.rep, x);
  343. }
  344.  
  345. inline int ucompare(long x, const Integer& y)
  346. {
  347.   return -ucompare(y.rep, x);
  348. }
  349.  
  350. inline void  add(const Integer& x, const Integer& y, Integer& dest)
  351. {
  352.   dest.rep = add(x.rep, 0, y.rep, 0, dest.rep);
  353. }
  354.  
  355. inline void  sub(const Integer& x, const Integer& y, Integer& dest)
  356. {
  357.   dest.rep = add(x.rep, 0, y.rep, 1, dest.rep);
  358. }
  359.  
  360. inline void  mul(const Integer& x, const Integer& y, Integer& dest)
  361. {
  362.   dest.rep = multiply(x.rep, y.rep, dest.rep);
  363. }
  364.  
  365. inline void  div(const Integer& x, const Integer& y, Integer& dest)
  366. {
  367.   dest.rep = div(x.rep, y.rep, dest.rep);
  368. }
  369.  
  370. inline void  mod(const Integer& x, const Integer& y, Integer& dest)
  371. {
  372.   dest.rep = mod(x.rep, y.rep, dest.rep);
  373. }
  374.  
  375. #ifndef __STRICT_ANSI__
  376. inline void  and(const Integer& x, const Integer& y, Integer& dest)
  377. {
  378.   dest.rep = bitop(x.rep, y.rep, dest.rep, '&');
  379. }
  380.  
  381. inline void  or(const Integer& x, const Integer& y, Integer& dest)
  382. {
  383.   dest.rep = bitop(x.rep, y.rep, dest.rep, '|');
  384. }
  385.  
  386. inline void  xor(const Integer& x, const Integer& y, Integer& dest)
  387. {
  388.   dest.rep = bitop(x.rep, y.rep, dest.rep, '^');
  389. }
  390. #endif
  391.  
  392. inline void  lshift(const Integer& x, const Integer& y, Integer& dest)
  393. {
  394.   dest.rep = lshift(x.rep, y.rep, 0, dest.rep);
  395. }
  396.  
  397. inline void  rshift(const Integer& x, const Integer& y, Integer& dest)
  398. {
  399.   dest.rep = lshift(x.rep, y.rep, 1, dest.rep);
  400. }
  401.  
  402. inline void  pow(const Integer& x, const Integer& y, Integer& dest)
  403. {
  404.   dest.rep = power(x.rep, Itolong(y.rep), dest.rep); // not incorrect
  405. }
  406.  
  407. inline void  add(const Integer& x, long y, Integer& dest)
  408. {
  409.   dest.rep = add(x.rep, 0, y, dest.rep);
  410. }
  411.  
  412. inline void  sub(const Integer& x, long y, Integer& dest)
  413. {
  414.   dest.rep = add(x.rep, 0, -y, dest.rep);
  415. }
  416.  
  417. inline void  mul(const Integer& x, long y, Integer& dest)
  418. {
  419.   dest.rep = multiply(x.rep, y, dest.rep);
  420. }
  421.  
  422. inline void  div(const Integer& x, long y, Integer& dest)
  423. {
  424.   dest.rep = div(x.rep, y, dest.rep);
  425. }
  426.  
  427. inline void  mod(const Integer& x, long y, Integer& dest)
  428. {
  429.   dest.rep = mod(x.rep, y, dest.rep);
  430. }
  431.  
  432. #ifndef __STRICT_ANSI__
  433. inline void  and(const Integer& x, long y, Integer& dest)
  434. {
  435.   dest.rep = bitop(x.rep, y, dest.rep, '&');
  436. }
  437.  
  438. inline void  or(const Integer& x, long y, Integer& dest)
  439. {
  440.   dest.rep = bitop(x.rep, y, dest.rep, '|');
  441. }
  442.  
  443. inline void  xor(const Integer& x, long y, Integer& dest)
  444. {
  445.   dest.rep = bitop(x.rep, y, dest.rep, '^');
  446. }
  447. #endif
  448.  
  449. inline void  lshift(const Integer& x, long y, Integer& dest)
  450. {
  451.   dest.rep = lshift(x.rep, y, dest.rep);
  452. }
  453.  
  454. inline void  rshift(const Integer& x, long y, Integer& dest)
  455. {
  456.   dest.rep = lshift(x.rep, -y, dest.rep);
  457. }
  458.  
  459. inline void  pow(const Integer& x, long y, Integer& dest)
  460. {
  461.   dest.rep = power(x.rep, y, dest.rep);
  462. }
  463.  
  464. inline void abs(const Integer& x, Integer& dest)
  465. {
  466.   dest.rep = abs(x.rep, dest.rep);
  467. }
  468.  
  469. inline void negate(const Integer& x, Integer& dest)
  470. {
  471.   dest.rep = negate(x.rep, dest.rep);
  472. }
  473.  
  474. inline void complement(const Integer& x, Integer& dest)
  475. {
  476.   dest.rep = compl(x.rep, dest.rep);
  477. }
  478.  
  479. inline void  add(long x, const Integer& y, Integer& dest)
  480. {
  481.   dest.rep = add(y.rep, 0, x, dest.rep);
  482. }
  483.  
  484. inline void  sub(long x, const Integer& y, Integer& dest)
  485. {
  486.   dest.rep = add(y.rep, 1, x, dest.rep);
  487. }
  488.  
  489. inline void  mul(long x, const Integer& y, Integer& dest)
  490. {
  491.   dest.rep = multiply(y.rep, x, dest.rep);
  492. }
  493.  
  494. #ifndef __STRICT_ANSI__
  495. inline void  and(long x, const Integer& y, Integer& dest)
  496. {
  497.   dest.rep = bitop(y.rep, x, dest.rep, '&');
  498. }
  499.  
  500. inline void  or(long x, const Integer& y, Integer& dest)
  501. {
  502.   dest.rep = bitop(y.rep, x, dest.rep, '|');
  503. }
  504.  
  505. inline void  xor(long x, const Integer& y, Integer& dest)
  506. {
  507.   dest.rep = bitop(y.rep, x, dest.rep, '^');
  508. }
  509. #endif
  510.  
  511.  
  512. // operator versions
  513.  
  514. inline int operator == (const Integer&  x, const Integer&  y)
  515. {
  516.   return compare(x, y) == 0; 
  517. }
  518.  
  519. inline int operator == (const Integer&  x, long y)
  520. {
  521.   return compare(x, y) == 0; 
  522. }
  523.  
  524. inline int operator != (const Integer&  x, const Integer&  y)
  525. {
  526.   return compare(x, y) != 0; 
  527. }
  528.  
  529. inline int operator != (const Integer&  x, long y)
  530. {
  531.   return compare(x, y) != 0; 
  532. }
  533.  
  534. inline int operator <  (const Integer&  x, const Integer&  y)
  535. {
  536.   return compare(x, y) <  0; 
  537. }
  538.  
  539. inline int operator <  (const Integer&  x, long y)
  540. {
  541.   return compare(x, y) <  0; 
  542. }
  543.  
  544. inline int operator <= (const Integer&  x, const Integer&  y)
  545. {
  546.   return compare(x, y) <= 0; 
  547. }
  548.  
  549. inline int operator <= (const Integer&  x, long y)
  550. {
  551.   return compare(x, y) <= 0; 
  552. }
  553.  
  554. inline int operator >  (const Integer&  x, const Integer&  y)
  555. {
  556.   return compare(x, y) >  0; 
  557. }
  558.  
  559. inline int operator >  (const Integer&  x, long y)
  560. {
  561.   return compare(x, y) >  0; 
  562. }
  563.  
  564. inline int operator >= (const Integer&  x, const Integer&  y)
  565. {
  566.   return compare(x, y) >= 0; 
  567. }
  568.  
  569. inline int operator >= (const Integer&  x, long y)
  570. {
  571.   return compare(x, y) >= 0; 
  572. }
  573.  
  574.  
  575. inline Integer&  Integer::operator += (const Integer& y)
  576. {
  577.   add(*this, y, *this);
  578.   return *this;
  579. }
  580.  
  581. inline Integer&  Integer::operator += (long y)
  582. {
  583.   add(*this, y, *this);
  584.   return *this;
  585. }
  586.  
  587. inline Integer& Integer::operator ++ ()
  588. {
  589.   add(*this, 1, *this);
  590.   return *this;
  591. }
  592.  
  593.  
  594. inline Integer& Integer::operator -= (const Integer& y)
  595. {
  596.   sub(*this, y, *this);
  597.   return *this;
  598. }
  599.  
  600. inline Integer& Integer::operator -= (long y)
  601. {
  602.   sub(*this, y, *this);
  603.   return *this;
  604. }
  605.  
  606. inline Integer& Integer::operator -- ()
  607. {
  608.   add(*this, -1, *this);
  609.   return *this;
  610. }
  611.  
  612.  
  613.  
  614. inline Integer& Integer::operator *= (const Integer& y)
  615. {
  616.   mul(*this, y, *this);
  617.   return *this;
  618. }
  619.  
  620. inline Integer& Integer::operator *= (long y)
  621. {
  622.   mul(*this, y, *this);
  623.   return *this;
  624. }
  625.  
  626.  
  627. inline Integer& Integer::operator &= (const Integer& y)
  628. {
  629.   rep = bitop(rep, y.rep, rep, '&');
  630.   return *this;
  631. }
  632.  
  633. inline Integer& Integer::operator &= (long y)
  634. {
  635.   rep = bitop(rep, y, rep, '&');
  636.   return *this;
  637. }
  638.  
  639. inline Integer& Integer::operator |= (const Integer& y)
  640. {
  641.   rep = bitop(rep, y.rep, rep, '|');
  642.   return *this;
  643. }
  644.  
  645. inline Integer& Integer::operator |= (long y)
  646. {
  647.   rep = bitop(rep, y, rep, '|');
  648.   return *this;
  649. }
  650.  
  651.  
  652. inline Integer& Integer::operator ^= (const Integer& y)
  653. {
  654.   rep = bitop(rep, y.rep, rep, '^');
  655.   return *this;
  656. }
  657.  
  658. inline Integer& Integer::operator ^= (long y)
  659. {
  660.   rep = bitop(rep, y, rep, '^');
  661.   return *this;
  662. }
  663.  
  664.  
  665.  
  666. inline Integer& Integer::operator /= (const Integer& y)
  667. {
  668.   div(*this, y, *this);
  669.   return *this;
  670. }
  671.  
  672. inline Integer& Integer::operator /= (long y)
  673. {
  674.   div(*this, y, *this);
  675.   return *this;
  676. }
  677.  
  678.  
  679. inline Integer& Integer::operator <<= (const Integer&  y)
  680. {
  681.   lshift(*this, y, *this);
  682.   return *this;
  683. }
  684.  
  685. inline Integer& Integer::operator <<= (long  y)
  686. {
  687.   lshift(*this, y, *this);
  688.   return *this;
  689. }
  690.  
  691.  
  692. inline Integer& Integer::operator >>= (const Integer&  y)
  693. {
  694.   rshift(*this, y, *this);
  695.   return *this;
  696. }
  697.  
  698. inline Integer& Integer::operator >>= (long y)
  699. {
  700.   rshift(*this, y, *this);
  701.   return *this;
  702. }
  703.  
  704. #if defined (__GNUG__) && ! defined (__STRICT_ANSI__)
  705. inline Integer operator <? (const Integer& x, const Integer& y)
  706. {
  707.   return (compare(x.rep, y.rep) <= 0) ? x : y;
  708. }
  709.  
  710. inline Integer operator >? (const Integer& x, const Integer& y)
  711. {
  712.   return (compare(x.rep, y.rep) >= 0)?  x : y;
  713. }
  714. #endif
  715.  
  716.  
  717. inline void Integer::abs()
  718. {
  719.   ::abs(*this, *this);
  720. }
  721.  
  722. inline void Integer::negate()
  723. {
  724.   ::negate(*this, *this);
  725. }
  726.  
  727.  
  728. inline void Integer::complement()
  729. {
  730.   ::complement(*this, *this);
  731. }
  732.  
  733.  
  734. inline int sign(const Integer& x)
  735. {
  736.   return (x.rep->len == 0) ? 0 : ( (x.rep->sgn == 1) ? 1 : -1 );
  737. }
  738.  
  739. inline int even(const Integer& y)
  740. {
  741.   return y.rep->len == 0 || !(y.rep->s[0] & 1);
  742. }
  743.  
  744. inline int odd(const Integer& y)
  745. {
  746.   return y.rep->len > 0 && (y.rep->s[0] & 1);
  747. }
  748.  
  749. inline char* Itoa(const Integer& y, int base, int width)
  750. {
  751.   return Itoa(y.rep, base, width);
  752. }
  753.  
  754.  
  755.  
  756. inline long lg(const Integer& x) 
  757. {
  758.   return lg(x.rep);
  759. }
  760.  
  761. // constructive operations 
  762.  
  763. #if defined(__GNUG__) && !defined(_G_NO_NRV)
  764.  
  765. inline Integer  operator +  (const Integer& x, const Integer& y) return r
  766. {
  767.   add(x, y, r);
  768. }
  769.  
  770. inline Integer  operator +  (const Integer& x, long y) return r
  771. {
  772.   add(x, y, r);
  773. }
  774.  
  775. inline Integer  operator +  (long  x, const Integer& y) return r
  776. {
  777.   add(x, y, r);
  778. }
  779.  
  780. inline Integer  operator -  (const Integer& x, const Integer& y) return r
  781. {
  782.   sub(x, y, r);
  783. }
  784.  
  785. inline Integer  operator -  (const Integer& x, long y) return r
  786. {
  787.   sub(x, y, r);
  788. }
  789.  
  790. inline Integer  operator -  (long  x, const Integer& y) return r
  791. {
  792.   sub(x, y, r);
  793. }
  794.  
  795. inline Integer  operator *  (const Integer& x, const Integer& y) return r
  796. {
  797.   mul(x, y, r);
  798. }
  799.  
  800. inline Integer  operator *  (const Integer& x, long y) return r
  801. {
  802.   mul(x, y, r);
  803. }
  804.  
  805. inline Integer  operator *  (long  x, const Integer& y) return r
  806. {
  807.   mul(x, y, r);
  808. }
  809.  
  810. inline Integer sqr(const Integer& x) return r
  811. {
  812.   mul(x, x, r);
  813. }
  814.  
  815. inline Integer  operator &  (const Integer& x, const Integer& y) return r
  816. {
  817.   r.rep = bitop(x.rep, y.rep, r.rep, '&');
  818. }
  819.  
  820. inline Integer  operator &  (const Integer& x, long y) return r
  821. {
  822.   r.rep = bitop(x.rep, y, r.rep, '&');
  823. }
  824.  
  825. inline Integer  operator &  (long  x, const Integer& y) return r
  826. {
  827.   r.rep = bitop(y.rep, x, r.rep, '&');
  828. }
  829.  
  830. inline Integer  operator |  (const Integer& x, const Integer& y) return r
  831. {
  832.   r.rep = bitop(x.rep, y.rep, r.rep, '|');
  833. }
  834.  
  835. inline Integer  operator |  (const Integer& x, long y) return r
  836. {
  837.   r.rep = bitop(x.rep, y, r.rep, '|');
  838. }
  839.  
  840. inline Integer  operator |  (long  x, const Integer& y) return r
  841. {
  842.   r.rep = bitop(y.rep, x, r.rep, '|');
  843. }
  844.  
  845. inline Integer  operator ^  (const Integer& x, const Integer& y) return r
  846. {
  847.   r.rep = bitop(x.rep, y.rep, r.rep, '^');
  848. }
  849.  
  850. inline Integer  operator ^  (const Integer& x, long y) return r
  851. {
  852.   r.rep = bitop (x.rep, y, r.rep, '^');
  853. }
  854.  
  855. inline Integer  operator ^  (long  x, const Integer& y) return r
  856. {
  857.   r.rep = bitop (y.rep, x, r.rep, '^');
  858. }
  859.  
  860. inline Integer  operator /  (const Integer& x, const Integer& y) return r
  861. {
  862.   div(x, y, r);
  863. }
  864.  
  865. inline Integer operator /  (const Integer& x, long y) return r
  866. {
  867.   div(x, y, r);
  868. }
  869.  
  870. inline Integer operator %  (const Integer& x, const Integer& y) return r
  871. {
  872.   mod(x, y, r);
  873. }
  874.  
  875. inline Integer operator %  (const Integer& x, long y) return r
  876. {
  877.   mod(x, y, r);
  878. }
  879.  
  880. inline Integer operator <<  (const Integer& x, const Integer& y) return r
  881. {
  882.   lshift(x, y, r);
  883. }
  884.  
  885. inline Integer operator <<  (const Integer& x, long y) return r
  886. {
  887.   lshift(x, y, r);
  888. }
  889.  
  890. inline Integer operator >>  (const Integer& x, const Integer& y) return r;
  891. {
  892.   rshift(x, y, r);
  893. }
  894.  
  895. inline Integer operator >>  (const Integer& x, long y) return r
  896. {
  897.   rshift(x, y, r);
  898. }
  899.  
  900. inline Integer pow(const Integer& x, long y) return r
  901. {
  902.   pow(x, y, r);
  903. }
  904.  
  905. inline Integer Ipow(long x, long y) return r(x)
  906. {
  907.   pow(r, y, r);
  908. }
  909.  
  910. inline Integer pow(const Integer& x, const Integer& y) return r
  911. {
  912.   pow(x, y, r);
  913. }
  914.  
  915.  
  916.  
  917. inline Integer abs(const Integer& x) return r
  918. {
  919.   abs(x, r);
  920. }
  921.  
  922. inline Integer operator - (const Integer& x) return r
  923. {
  924.   negate(x, r);
  925. }
  926.  
  927. inline Integer operator ~ (const Integer& x) return r
  928. {
  929.   complement(x, r);
  930. }
  931.  
  932. inline Integer  atoI(const char* s, int base) return r
  933. {
  934.   r.rep = atoIntRep(s, base);
  935. }
  936.  
  937. inline Integer  gcd(const Integer& x, const Integer& y) return r
  938. {
  939.   r.rep = gcd(x.rep, y.rep);
  940. }
  941.  
  942. #else /* NO_NRV */
  943.  
  944. inline Integer  operator +  (const Integer& x, const Integer& y) 
  945. {
  946.   Integer r; add(x, y, r); return r;
  947. }
  948.  
  949. inline Integer  operator +  (const Integer& x, long y) 
  950. {
  951.   Integer r; add(x, y, r); return r;
  952. }
  953.  
  954. inline Integer  operator +  (long  x, const Integer& y) 
  955. {
  956.   Integer r; add(x, y, r); return r;
  957. }
  958.  
  959. inline Integer  operator -  (const Integer& x, const Integer& y) 
  960. {
  961.   Integer r; sub(x, y, r); return r;
  962. }
  963.  
  964. inline Integer  operator -  (const Integer& x, long y) 
  965. {
  966.   Integer r; sub(x, y, r); return r;
  967. }
  968.  
  969. inline Integer  operator -  (long  x, const Integer& y) 
  970. {
  971.   Integer r; sub(x, y, r); return r;
  972. }
  973.  
  974. inline Integer  operator *  (const Integer& x, const Integer& y) 
  975. {
  976.   Integer r; mul(x, y, r); return r;
  977. }
  978.  
  979. inline Integer  operator *  (const Integer& x, long y) 
  980. {
  981.   Integer r; mul(x, y, r); return r;
  982. }
  983.  
  984. inline Integer  operator *  (long  x, const Integer& y) 
  985. {
  986.   Integer r; mul(x, y, r); return r;
  987. }
  988.  
  989. inline Integer sqr(const Integer& x) 
  990. {
  991.   Integer r; mul(x, x, r); return r;
  992. }
  993.  
  994. inline Integer  operator &  (const Integer& x, const Integer& y) 
  995. {
  996.   Integer r; and(x, y, r); return r;
  997. }
  998.  
  999. inline Integer  operator &  (const Integer& x, long y) 
  1000. {
  1001.   Integer r; and(x, y, r); return r;
  1002. }
  1003.  
  1004. inline Integer  operator &  (long  x, const Integer& y) 
  1005. {
  1006.   Integer r; and(x, y, r); return r;
  1007. }
  1008.  
  1009. inline Integer  operator |  (const Integer& x, const Integer& y) 
  1010. {
  1011.   Integer r; or(x, y, r); return r;
  1012. }
  1013.  
  1014. inline Integer  operator |  (const Integer& x, long y) 
  1015. {
  1016.   Integer r; or(x, y, r); return r;
  1017. }
  1018.  
  1019. inline Integer  operator |  (long  x, const Integer& y) 
  1020. {
  1021.   Integer r; or(x, y, r); return r;
  1022. }
  1023.  
  1024. inline Integer  operator ^  (const Integer& x, const Integer& y) 
  1025. {
  1026.   Integer r; r.rep = bitop(x.rep, y.rep, r.rep, '^'); return r;
  1027. }
  1028.  
  1029. inline Integer  operator ^  (const Integer& x, long y) 
  1030. {
  1031.   Integer r; r.rep = bitop(x.rep, y, r.rep, '^'); return r;
  1032. }
  1033.  
  1034. inline Integer  operator ^  (long  x, const Integer& y) 
  1035. {
  1036.   Integer r; r.rep = bitop(y.rep, x, r.rep, '^'); return r;
  1037. }
  1038.  
  1039. inline Integer  operator /  (const Integer& x, const Integer& y) 
  1040. {
  1041.   Integer r; div(x, y, r); return r;
  1042. }
  1043.  
  1044. inline Integer operator /  (const Integer& x, long y) 
  1045. {
  1046.   Integer r; div(x, y, r); return r;
  1047. }
  1048.  
  1049. inline Integer operator %  (const Integer& x, const Integer& y) 
  1050. {
  1051.   Integer r; mod(x, y, r); return r;
  1052. }
  1053.  
  1054. inline Integer operator %  (const Integer& x, long y) 
  1055. {
  1056.   Integer r; mod(x, y, r); return r;
  1057. }
  1058.  
  1059. inline Integer operator <<  (const Integer& x, const Integer& y) 
  1060. {
  1061.   Integer r; lshift(x, y, r); return r;
  1062. }
  1063.  
  1064. inline Integer operator <<  (const Integer& x, long y) 
  1065. {
  1066.   Integer r; lshift(x, y, r); return r;
  1067. }
  1068.  
  1069. inline Integer operator >>  (const Integer& x, const Integer& y) 
  1070. {
  1071.   Integer r; rshift(x, y, r); return r;
  1072. }
  1073.  
  1074. inline Integer operator >>  (const Integer& x, long y) 
  1075. {
  1076.   Integer r; rshift(x, y, r); return r;
  1077. }
  1078.  
  1079. inline Integer pow(const Integer& x, long y) 
  1080. {
  1081.   Integer r; pow(x, y, r); return r;
  1082. }
  1083.  
  1084. inline Integer Ipow(long x, long y) 
  1085. {
  1086.   Integer r(x); pow(r, y, r); return r;
  1087. }
  1088.  
  1089. inline Integer pow(const Integer& x, const Integer& y) 
  1090. {
  1091.   Integer r; pow(x, y, r); return r;
  1092. }
  1093.  
  1094.  
  1095.  
  1096. inline Integer abs(const Integer& x) 
  1097. {
  1098.   Integer r; abs(x, r); return r;
  1099. }
  1100.  
  1101. inline Integer operator - (const Integer& x) 
  1102. {
  1103.   Integer r; negate(x, r); return r;
  1104. }
  1105.  
  1106. inline Integer operator ~ (const Integer& x) 
  1107. {
  1108.   Integer r; complement(x, r); return r;
  1109. }
  1110.  
  1111. inline Integer  atoI(const char* s, int base) 
  1112. {
  1113.   Integer r; r.rep = atoIntRep(s, base); return r;
  1114. }
  1115.  
  1116. inline Integer  gcd(const Integer& x, const Integer& y) 
  1117. {
  1118.   Integer r; r.rep = gcd(x.rep, y.rep); return r;
  1119. }
  1120.  
  1121. #endif  /* NO_NRV */
  1122.  
  1123. inline Integer& Integer::operator %= (const Integer& y)
  1124. {
  1125.   *this = *this % y; // mod(*this, y, *this) doesn't work.
  1126.   return *this;
  1127. }
  1128.  
  1129. inline Integer& Integer::operator %= (long y)
  1130. {
  1131.   *this = *this % y; // mod(*this, y, *this) doesn't work.
  1132.   return *this;
  1133. }
  1134. #endif /* !_Integer_h */
  1135.