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