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