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