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