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