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