f0047325a397d05e82cba9c8ea4006be7598ae8e
[ACL.git] / src / Integer.h
1 // This may look like C code, but it is really -*- C++ -*-
2
3 /* 
4 Copyright (C) 1988 Free Software Foundation
5     written by Doug Lea (dl@rocky.oswego.edu)
6
7 This file is part of the GNU C++ Library.  This library is free
8 software; you can redistribute it and/or modify it under the terms of
9 the GNU Library General Public License as published by the Free
10 Software Foundation; either version 2 of the License, or (at your
11 option) any later version.  This library is distributed in the hope
12 that it will be useful, but WITHOUT ANY WARRANTY; without even the
13 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE.  See the GNU Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #ifndef _Integer_h
21 #ifdef __GNUG__
22 #pragma interface
23 #endif
24 #define _Integer_h 1
25
26 #include <iostream>
27
28 struct IntRep                    // internal Integer representations
29 {
30   unsigned short  len;          // current length
31   unsigned short  sz;           // allocated space (0 means static).
32   short           sgn;          // 1 means >= 0; 0 means < 0 
33   unsigned short  s[1];         // represented as ushort array starting here
34 };
35
36 // True if REP is staticly (or manually) allocated,
37 // and should not be deleted by an Integer destructor.
38 #define STATIC_IntRep(rep) ((rep)->sz==0)
39
40 extern IntRep*  Ialloc(IntRep*, const unsigned short *, int, int, int);
41 extern IntRep*  Icalloc(IntRep*, int);
42 extern IntRep*  Icopy_ulong(IntRep*, unsigned long);
43 extern IntRep*  Icopy_long(IntRep*, long);
44 extern IntRep*  Icopy(IntRep*, const IntRep*);
45 extern IntRep*  Iresize(IntRep*, int);
46 extern IntRep*  add(const IntRep*, int, const IntRep*, int, IntRep*);
47 extern IntRep*  add(const IntRep*, int, long, IntRep*);
48 extern IntRep*  multiply(const IntRep*, const IntRep*, IntRep*);
49 extern IntRep*  multiply(const IntRep*, long, IntRep*);
50 extern IntRep*  lshift(const IntRep*, long, IntRep*);
51 extern IntRep*  lshift(const IntRep*, const IntRep*, int, IntRep*);
52 extern IntRep*  bitop(const IntRep*, const IntRep*, IntRep*, char);
53 extern IntRep*  bitop(const IntRep*, long, IntRep*, char);
54 extern IntRep*  power(const IntRep*, long, IntRep*);
55 extern IntRep*  div(const IntRep*, const IntRep*, IntRep*);
56 extern IntRep*  mod(const IntRep*, const IntRep*, IntRep*);
57 extern IntRep*  div(const IntRep*, long, IntRep*);
58 extern IntRep*  mod(const IntRep*, long, IntRep*);
59 extern IntRep*  I_compl(const IntRep*, IntRep*);
60 extern IntRep*  abs(const IntRep*, IntRep*);
61 extern IntRep*  negate(const IntRep*, IntRep*);
62 extern IntRep*  pow(const IntRep*, long);
63 extern IntRep*  gcd(const IntRep*, const IntRep* y);
64 extern int      compare(const IntRep*, const IntRep*);
65 extern int      compare(const IntRep*, long);
66 extern int      ucompare(const IntRep*, const IntRep*);
67 extern int      ucompare(const IntRep*, long);
68 extern char*    Itoa(const IntRep* x, int base = 10, int width = 0);
69 extern char*    cvtItoa(const IntRep* x, char* fmt, int& fmtlen, int base,
70                         int showbase, int width, int align_right, 
71                         char fillchar, char Xcase, int showpos);
72 extern IntRep*  atoIntRep(const char* s, int base = 10);
73 extern long     Itolong(const IntRep*);
74 extern double   Itodouble(const IntRep*);
75 extern int      Iislong(const IntRep*);
76 extern int      Iisdouble(const IntRep*);
77 extern long     lg(const IntRep*);
78
79 extern IntRep _ZeroRep, _OneRep, _MinusOneRep;
80
81 class Integer
82 {
83 protected:
84   IntRep*         rep;
85 public:
86                   Integer();
87                   Integer(long);
88                   Integer(unsigned long);
89                   Integer(IntRep*);
90                   Integer(const Integer&);
91
92                   ~Integer();
93
94   void            operator =  (const Integer&);
95   void            operator =  (long);
96
97 // unary operations to self
98
99   void            operator ++ ();
100   void            operator -- ();
101   void            negate();          // negate in-place
102   void            abs();             // absolute-value in-place
103   void            complement();      // bitwise complement in-place
104
105 // assignment-based operations
106
107   void            operator += (const Integer&);
108   void            operator -= (const Integer&);
109   void            operator *= (const Integer&);
110   void            operator /= (const Integer&);
111   void            operator %= (const Integer&);
112   void            operator <<=(const Integer&);
113   void            operator >>=(const Integer&);
114   void            operator &= (const Integer&);
115   void            operator |= (const Integer&);
116   void            operator ^= (const Integer&);
117
118   void            operator += (long);
119   void            operator -= (long);
120   void            operator *= (long);
121   void            operator /= (long);
122   void            operator %= (long);
123   void            operator <<=(long);
124   void            operator >>=(long);
125   void            operator &= (long);
126   void            operator |= (long);
127   void            operator ^= (long);
128
129 // (constructive binary operations are inlined below)
130
131 #ifdef __GNUG__
132   //friend Integer operator <? (const Integer& x, const Integer& y); // min
133   //friend Integer operator >? (const Integer& x, const Integer& y); // max
134 #endif
135
136 // builtin Integer functions that must be friends
137
138   friend long     lg (const Integer&); // floor log base 2 of abs(x)
139   friend double   ratio(const Integer& x, const Integer& y);
140                   // return x/y as a double
141
142   friend Integer  gcd(const Integer&, const Integer&);
143   friend int      even(const Integer&); // true if even
144   friend int      odd(const Integer&); // true if odd
145   friend int      sign(const Integer&); // returns -1, 0, +1
146
147   friend void     (setbit)(Integer& x, long b);   // set b'th bit of x
148   friend void     clearbit(Integer& x, long b); // clear b'th bit
149   friend int      testbit(const Integer& x, long b);  // return b'th bit
150
151 // procedural versions of operators
152
153   friend void     abs(const Integer& x, Integer& dest);
154   friend void     negate(const Integer& x, Integer& dest);
155   friend void     complement(const Integer& x, Integer& dest);
156
157   friend int      compare(const Integer&, const Integer&);  
158   friend int      ucompare(const Integer&, const Integer&); 
159   friend void     add(const Integer& x, const Integer& y, Integer& dest);
160   friend void     sub(const Integer& x, const Integer& y, Integer& dest);
161   friend void     mul(const Integer& x, const Integer& y, Integer& dest);
162   friend void     div(const Integer& x, const Integer& y, Integer& dest);
163   friend void     mod(const Integer& x, const Integer& y, Integer& dest);
164   friend void     divide(const Integer& x, const Integer& y, 
165                          Integer& q, Integer& r);
166   friend void     I_and(const Integer& x, const Integer& y, Integer& dest);
167   friend void     I_or(const Integer& x, const Integer& y, Integer& dest);
168   friend void     I_xor(const Integer& x, const Integer& y, Integer& dest);
169   friend void     lshift(const Integer& x, const Integer& y, Integer& dest);
170   friend void     rshift(const Integer& x, const Integer& y, Integer& dest);
171   friend void     pow(const Integer& x, const Integer& y, Integer& dest);
172
173   friend int      compare(const Integer&, long);  
174   friend int      ucompare(const Integer&, long); 
175   friend void     add(const Integer& x, long y, Integer& dest);
176   friend void     sub(const Integer& x, long y, Integer& dest);
177   friend void     mul(const Integer& x, long y, Integer& dest);
178   friend void     div(const Integer& x, long y, Integer& dest);
179   friend void     mod(const Integer& x, long y, Integer& dest);
180   friend void     divide(const Integer& x, long y, Integer& q, long& r);
181   friend void     I_and(const Integer& x, long y, Integer& dest);
182   friend void     I_or(const Integer& x, long y, Integer& dest);
183   friend void     I_xor(const Integer& x, long y, Integer& dest);
184   friend void     lshift(const Integer& x, long y, Integer& dest);
185   friend void     rshift(const Integer& x, long y, Integer& dest);
186   friend void     pow(const Integer& x, long y, Integer& dest);
187
188   friend int      compare(long, const Integer&);  
189   friend int      ucompare(long, const Integer&); 
190   friend void     add(long x, const Integer& y, Integer& dest);
191   friend void     sub(long x, const Integer& y, Integer& dest);
192   friend void     mul(long x, const Integer& y, Integer& dest);
193   friend void     I_and(long x, const Integer& y, Integer& dest);
194   friend void     I_or(long x, const Integer& y, Integer& dest);
195   friend void     I_xor(long x, const Integer& y, Integer& dest);
196
197 // coercion & conversion
198
199   int             fits_in_long() const;
200   int             fits_in_double() const;
201
202                   operator long() const;
203                   operator double() const;
204
205   friend char*    Itoa(const Integer& x, int base = 10, int width = 0);
206   friend Integer  atoI(const char* s, int base = 10);
207   void            printon(std::ostream& s, int base = 10, int width = 0) const;
208   
209   friend std::istream& operator >> (std::istream& s, Integer& y);
210   friend std::ostream& operator << (std::ostream& s, const Integer& y);
211
212 // error detection
213
214   int             initialized() const;
215   void   error(const char* msg) const;
216   int             OK() const;  
217 };
218
219
220 //  (These are declared inline)
221
222   int      operator == (const Integer&, const Integer&);
223   int      operator == (const Integer&, long);
224   int      operator != (const Integer&, const Integer&);
225   int      operator != (const Integer&, long);
226   int      operator <  (const Integer&, const Integer&);
227   int      operator <  (const Integer&, long);
228   int      operator <= (const Integer&, const Integer&);
229   int      operator <= (const Integer&, long);
230   int      operator >  (const Integer&, const Integer&);
231   int      operator >  (const Integer&, long);
232   int      operator >= (const Integer&, const Integer&);
233   int      operator >= (const Integer&, long);
234   Integer  operator -  (const Integer&);
235   Integer  operator ~  (const Integer&);
236   Integer  operator +  (const Integer&, const Integer&);
237   Integer  operator +  (const Integer&, long);
238   Integer  operator +  (long, const Integer&);
239   Integer  operator -  (const Integer&, const Integer&);
240   Integer  operator -  (const Integer&, long);
241   Integer  operator -  (long, const Integer&);
242   Integer  operator *  (const Integer&, const Integer&);
243   Integer  operator *  (const Integer&, long);
244   Integer  operator *  (long, const Integer&);
245   Integer  operator /  (const Integer&, const Integer&);
246   Integer  operator /  (const Integer&, long);
247   Integer  operator %  (const Integer&, const Integer&);
248   Integer  operator %  (const Integer&, long);
249   Integer  operator << (const Integer&, const Integer&);
250   Integer  operator << (const Integer&, long);
251   Integer  operator >> (const Integer&, const Integer&);
252   Integer  operator >> (const Integer&, long);
253   Integer  operator &  (const Integer&, const Integer&);
254   Integer  operator &  (const Integer&, long);
255   Integer  operator &  (long, const Integer&);
256   Integer  operator |  (const Integer&, const Integer&);
257   Integer  operator |  (const Integer&, long);
258   Integer  operator |  (long, const Integer&);
259   Integer  operator ^  (const Integer&, const Integer&);
260   Integer  operator ^  (const Integer&, long);
261   Integer  operator ^  (long, const Integer&);
262
263   Integer  abs(const Integer&); // absolute value
264   Integer  sqr(const Integer&); // square
265
266   Integer  pow(const Integer& x, const Integer& y);
267   Integer  pow(const Integer& x, long y);
268   Integer  Ipow(long x, long y); // x to the y as Integer 
269
270
271 extern char*    dec(const Integer& x, int width = 0);
272 extern char*    oct(const Integer& x, int width = 0);
273 extern char*    hex(const Integer& x, int width = 0);
274 extern Integer  sqrt(const Integer&); // floor of square root
275 extern Integer  lcm(const Integer& x, const Integer& y); // least common mult
276
277
278 typedef Integer IntTmp; // for backward compatibility
279
280 inline Integer::Integer() :rep(&_ZeroRep) {}
281
282 inline Integer::Integer(IntRep* r) :rep(r) {}
283
284 inline Integer::Integer(long y) :rep(Icopy_long(0, y)) {}
285
286 inline Integer::Integer(unsigned long y) :rep(Icopy_ulong(0, y)) {}
287
288 inline Integer::Integer(const Integer&  y) :rep(Icopy(0, y.rep)) {}
289
290 inline Integer::~Integer() { if (rep && !STATIC_IntRep(rep)) delete rep; }
291
292 inline void  Integer::operator = (const Integer&  y)
293 {
294   rep = Icopy(rep, y.rep);
295 }
296
297 inline void Integer::operator = (long y)
298 {
299   rep = Icopy_long(rep, y); 
300 }
301
302 inline Integer::operator long() const
303
304   return Itolong(rep);
305 }
306
307 inline int Integer::initialized() const
308 {
309   return rep != 0;
310 }
311
312 inline int Integer::fits_in_long() const
313 {
314   return Iislong(rep);
315 }
316
317 inline Integer::operator double() const
318
319   return Itodouble(rep);
320 }
321
322 inline int Integer::fits_in_double() const
323 {
324   return Iisdouble(rep);
325 }
326
327 // procedural versions
328
329 inline int compare(const Integer& x, const Integer& y)
330 {
331   return compare(x.rep, y.rep);
332 }
333
334 inline int ucompare(const Integer& x, const Integer& y)
335 {
336   return ucompare(x.rep, y.rep);
337 }
338
339 inline int compare(const Integer& x, long y)
340 {
341   return compare(x.rep, y);
342 }
343
344 inline int ucompare(const Integer& x, long y)
345 {
346   return ucompare(x.rep, y);
347 }
348
349 inline int compare(long x, const Integer& y)
350 {
351   return -compare(y.rep, x);
352 }
353
354 inline int ucompare(long x, const Integer& y)
355 {
356   return -ucompare(y.rep, x);
357 }
358
359 inline void  add(const Integer& x, const Integer& y, Integer& dest)
360 {
361   dest.rep = add(x.rep, 0, y.rep, 0, dest.rep);
362 }
363
364 inline void  sub(const Integer& x, const Integer& y, Integer& dest)
365 {
366   dest.rep = add(x.rep, 0, y.rep, 1, dest.rep);
367 }
368
369 inline void  mul(const Integer& x, const Integer& y, Integer& dest)
370 {
371   dest.rep = multiply(x.rep, y.rep, dest.rep);
372 }
373
374 inline void  div(const Integer& x, const Integer& y, Integer& dest)
375 {
376   dest.rep = div(x.rep, y.rep, dest.rep);
377 }
378
379 inline void  mod(const Integer& x, const Integer& y, Integer& dest)
380 {
381   dest.rep = mod(x.rep, y.rep, dest.rep);
382 }
383
384 inline void  I_and(const Integer& x, const Integer& y, Integer& dest)
385 {
386   dest.rep = bitop(x.rep, y.rep, dest.rep, '&');
387 }
388
389 inline void  I_or(const Integer& x, const Integer& y, Integer& dest)
390 {
391   dest.rep = bitop(x.rep, y.rep, dest.rep, '|');
392 }
393
394 inline void  I_xor(const Integer& x, const Integer& y, Integer& dest)
395 {
396   dest.rep = bitop(x.rep, y.rep, dest.rep, '^');
397 }
398
399 inline void  lshift(const Integer& x, const Integer& y, Integer& dest)
400 {
401   dest.rep = lshift(x.rep, y.rep, 0, dest.rep);
402 }
403
404 inline void  rshift(const Integer& x, const Integer& y, Integer& dest)
405 {
406   dest.rep = lshift(x.rep, y.rep, 1, dest.rep);
407 }
408
409 inline void  pow(const Integer& x, const Integer& y, Integer& dest)
410 {
411   dest.rep = power(x.rep, long(y), dest.rep); // not incorrect
412 }
413
414 inline void  add(const Integer& x, long y, Integer& dest)
415 {
416   dest.rep = add(x.rep, 0, y, dest.rep);
417 }
418
419 inline void  sub(const Integer& x, long y, Integer& dest)
420 {
421   dest.rep = add(x.rep, 0, -y, dest.rep);
422 }
423
424 inline void  mul(const Integer& x, long y, Integer& dest)
425 {
426   dest.rep = multiply(x.rep, y, dest.rep);
427 }
428
429 inline void  div(const Integer& x, long y, Integer& dest)
430 {
431   dest.rep = div(x.rep, y, dest.rep);
432 }
433
434 inline void  mod(const Integer& x, long y, Integer& dest)
435 {
436   dest.rep = mod(x.rep, y, dest.rep);
437 }
438
439 inline void  I_and(const Integer& x, long y, Integer& dest)
440 {
441   dest.rep = bitop(x.rep, y, dest.rep, '&');
442 }
443
444 inline void  I_or(const Integer& x, long y, Integer& dest)
445 {
446   dest.rep = bitop(x.rep, y, dest.rep, '|');
447 }
448
449 inline void  I_xor(const Integer& x, long y, Integer& dest)
450 {
451   dest.rep = bitop(x.rep, y, dest.rep, '^');
452 }
453
454 inline void  lshift(const Integer& x, long y, Integer& dest)
455 {
456   dest.rep = lshift(x.rep, y, dest.rep);
457 }
458
459 inline void  rshift(const Integer& x, long y, Integer& dest)
460 {
461   dest.rep = lshift(x.rep, -y, dest.rep);
462 }
463
464 inline void  pow(const Integer& x, long y, Integer& dest)
465 {
466   dest.rep = power(x.rep, y, dest.rep);
467 }
468
469 inline void abs(const Integer& x, Integer& dest)
470 {
471   dest.rep = abs(x.rep, dest.rep);
472 }
473
474 inline void negate(const Integer& x, Integer& dest)
475 {
476   dest.rep = negate(x.rep, dest.rep);
477 }
478
479 inline void complement(const Integer& x, Integer& dest)
480 {
481   dest.rep = I_compl(x.rep, dest.rep);
482 }
483
484 inline void  add(long x, const Integer& y, Integer& dest)
485 {
486   dest.rep = add(y.rep, 0, x, dest.rep);
487 }
488
489 inline void  sub(long x, const Integer& y, Integer& dest)
490 {
491   dest.rep = add(y.rep, 1, x, dest.rep);
492 }
493
494 inline void  mul(long x, const Integer& y, Integer& dest)
495 {
496   dest.rep = multiply(y.rep, x, dest.rep);
497 }
498
499 inline void  I_and(long x, const Integer& y, Integer& dest)
500 {
501   dest.rep = bitop(y.rep, x, dest.rep, '&');
502 }
503
504 inline void  I_or(long x, const Integer& y, Integer& dest)
505 {
506   dest.rep = bitop(y.rep, x, dest.rep, '|');
507 }
508
509 inline void  I_xor(long x, const Integer& y, Integer& dest)
510 {
511   dest.rep = bitop(y.rep, x, dest.rep, '^');
512 }
513
514
515 // operator versions
516
517 inline int operator == (const Integer&  x, const Integer&  y)
518 {
519   return compare(x, y) == 0; 
520 }
521
522 inline int operator == (const Integer&  x, long y)
523 {
524   return compare(x, y) == 0; 
525 }
526
527 inline int operator != (const Integer&  x, const Integer&  y)
528 {
529   return compare(x, y) != 0; 
530 }
531
532 inline int operator != (const Integer&  x, long y)
533 {
534   return compare(x, y) != 0; 
535 }
536
537 inline int operator <  (const Integer&  x, const Integer&  y)
538 {
539   return compare(x, y) <  0; 
540 }
541
542 inline int operator <  (const Integer&  x, long y)
543 {
544   return compare(x, y) <  0; 
545 }
546
547 inline int operator <= (const Integer&  x, const Integer&  y)
548 {
549   return compare(x, y) <= 0; 
550 }
551
552 inline int operator <= (const Integer&  x, long y)
553 {
554   return compare(x, y) <= 0; 
555 }
556
557 inline int operator >  (const Integer&  x, const Integer&  y)
558 {
559   return compare(x, y) >  0; 
560 }
561
562 inline int operator >  (const Integer&  x, long y)
563 {
564   return compare(x, y) >  0; 
565 }
566
567 inline int operator >= (const Integer&  x, const Integer&  y)
568 {
569   return compare(x, y) >= 0; 
570 }
571
572 inline int operator >= (const Integer&  x, long y)
573 {
574   return compare(x, y) >= 0; 
575 }
576
577
578 inline void  Integer::operator += (const Integer& y)
579 {
580   add(*this, y, *this);
581 }
582
583 inline void  Integer::operator += (long y)
584 {
585   add(*this, y, *this);
586 }
587
588 inline void Integer::operator ++ ()
589 {
590   add(*this, 1, *this);
591 }
592
593
594 inline void  Integer::operator -= (const Integer& y)
595 {
596   sub(*this, y, *this);
597 }
598
599 inline void  Integer::operator -= (long y)
600 {
601   sub(*this, y, *this);
602 }
603
604 inline void Integer::operator -- ()
605 {
606   add(*this, -1, *this);
607 }
608
609
610
611 inline void Integer::operator *= (const Integer& y)
612 {
613   mul(*this, y, *this);
614 }
615
616 inline void Integer::operator *= (long y)
617 {
618   mul(*this, y, *this);
619 }
620
621
622 inline void  Integer::operator &= (const Integer& y)
623 {
624   I_and(*this, y, *this);
625 }
626
627 inline void  Integer::operator &= (long y)
628 {
629   I_and(*this, y, *this);
630 }
631
632 inline void  Integer::operator |= (const Integer& y)
633 {
634   I_or(*this, y, *this);
635 }
636
637 inline void  Integer::operator |= (long y)
638 {
639   I_or(*this, y, *this);
640 }
641
642
643 inline void  Integer::operator ^= (const Integer& y)
644 {
645   I_xor(*this, y, *this);
646 }
647
648 inline void  Integer::operator ^= (long y)
649 {
650   I_xor(*this, y, *this);
651 }
652
653
654
655 inline void Integer::operator /= (const Integer& y)
656 {
657   div(*this, y, *this);
658 }
659
660 inline void Integer::operator /= (long y)
661 {
662   div(*this, y, *this);
663 }
664
665
666 inline void Integer::operator %= (const Integer& y)
667 {
668   *this = *this % y; // mod(*this, y, *this) doesn't work.
669 }
670
671 inline void Integer::operator %= (long y)
672 {
673   *this = *this % y; // mod(*this, y, *this) doesn't work.
674 }
675
676
677 inline void Integer::operator <<= (const Integer&  y)
678 {
679   lshift(*this, y, *this);
680 }
681
682 inline void Integer::operator <<= (long  y)
683 {
684   lshift(*this, y, *this);
685 }
686
687
688 inline void Integer::operator >>= (const Integer&  y)
689 {
690   rshift(*this, y, *this);
691 }
692
693 inline void  Integer::operator >>= (long y)
694 {
695   rshift(*this, y, *this);
696 }
697
698 #ifdef __GNUG__
699 /*
700 inline Integer operator <? (const Integer& x, const Integer& y)
701 {
702   return (compare(x.rep, y.rep) <= 0) ? x : y;
703 }
704
705 inline Integer operator >? (const Integer& x, const Integer& y)
706 {
707   return (compare(x.rep, y.rep) >= 0)?  x : y;
708 }
709 */
710 #endif
711
712
713 inline void Integer::abs()
714 {
715   ::abs(*this, *this);
716 }
717
718 inline void Integer::negate()
719 {
720   ::negate(*this, *this);
721 }
722
723
724 inline void Integer::complement()
725 {
726   ::complement(*this, *this);
727 }
728
729
730 inline int sign(const Integer& x)
731 {
732   return (x.rep->len == 0) ? 0 : ( (x.rep->sgn == 1) ? 1 : -1 );
733 }
734
735 inline int even(const Integer& y)
736 {
737   return y.rep->len == 0 || !(y.rep->s[0] & 1);
738 }
739
740 inline int odd(const Integer& y)
741 {
742   return y.rep->len > 0 && (y.rep->s[0] & 1);
743 }
744
745 inline char* Itoa(const Integer& y, int base, int width)
746 {
747   return Itoa(y.rep, base, width);
748 }
749
750
751
752 inline long lg(const Integer& x) 
753 {
754   return lg(x.rep);
755 }
756
757 // constructive operations 
758
759 inline Integer  operator +  (const Integer& x, const Integer& y) 
760 {
761   Integer r; add(x, y, r); return r;
762 }
763
764 inline Integer  operator +  (const Integer& x, long y) 
765 {
766   Integer r; add(x, y, r); return r;
767 }
768
769 inline Integer  operator +  (long  x, const Integer& y) 
770 {
771   Integer r; add(x, y, r); return r;
772 }
773
774 inline Integer  operator -  (const Integer& x, const Integer& y) 
775 {
776   Integer r; sub(x, y, r); return r;
777 }
778
779 inline Integer  operator -  (const Integer& x, long y) 
780 {
781   Integer r; sub(x, y, r); return r;
782 }
783
784 inline Integer  operator -  (long  x, const Integer& y) 
785 {
786   Integer r; sub(x, y, r); return r;
787 }
788
789 inline Integer  operator *  (const Integer& x, const Integer& y) 
790 {
791   Integer r; mul(x, y, r); return r;
792 }
793
794 inline Integer  operator *  (const Integer& x, long y) 
795 {
796   Integer r; mul(x, y, r); return r;
797 }
798
799 inline Integer  operator *  (long  x, const Integer& y) 
800 {
801   Integer r; mul(x, y, r); return r;
802 }
803
804 inline Integer sqr(const Integer& x) 
805 {
806   Integer r; mul(x, x, r); return r;
807 }
808
809 inline Integer  operator &  (const Integer& x, const Integer& y) 
810 {
811   Integer r; I_and(x, y, r); return r;
812 }
813
814 inline Integer  operator &  (const Integer& x, long y) 
815 {
816   Integer r; I_and(x, y, r); return r;
817 }
818
819 inline Integer  operator &  (long  x, const Integer& y) 
820 {
821   Integer r; I_and(x, y, r); return r;
822 }
823
824 inline Integer  operator |  (const Integer& x, const Integer& y) 
825 {
826   Integer r; I_or(x, y, r); return r;
827 }
828
829 inline Integer  operator |  (const Integer& x, long y) 
830 {
831   Integer r; I_or(x, y, r); return r;
832 }
833
834 inline Integer  operator |  (long  x, const Integer& y) 
835 {
836   Integer r; I_or(x, y, r); return r;
837 }
838
839 inline Integer  operator ^  (const Integer& x, const Integer& y) 
840 {
841   Integer r; I_xor(x, y, r); return r;
842 }
843
844 inline Integer  operator ^  (const Integer& x, long y) 
845 {
846   Integer r; I_xor(x, y, r); return r;
847 }
848
849 inline Integer  operator ^  (long  x, const Integer& y) 
850 {
851   Integer r; I_xor(x, y, r); return r;
852 }
853
854 inline Integer  operator /  (const Integer& x, const Integer& y) 
855 {
856   Integer r; div(x, y, r); return r;
857 }
858
859 inline Integer operator /  (const Integer& x, long y) 
860 {
861   Integer r; div(x, y, r); return r;
862 }
863
864 inline Integer operator %  (const Integer& x, const Integer& y) 
865 {
866   Integer r; mod(x, y, r); return r;
867 }
868
869 inline Integer operator %  (const Integer& x, long y) 
870 {
871   Integer r; mod(x, y, r); return r;
872 }
873
874 inline Integer operator <<  (const Integer& x, const Integer& y) 
875 {
876   Integer r; lshift(x, y, r); return r;
877 }
878
879 inline Integer operator <<  (const Integer& x, long y) 
880 {
881   Integer r; lshift(x, y, r); return r;
882 }
883
884 inline Integer operator >>  (const Integer& x, const Integer& y) 
885 {
886   Integer r; rshift(x, y, r); return r;
887 }
888
889 inline Integer operator >>  (const Integer& x, long y) 
890 {
891   Integer r; rshift(x, y, r); return r;
892 }
893
894 inline Integer pow(const Integer& x, long y) 
895 {
896   Integer r; pow(x, y, r); return r;
897 }
898
899 inline Integer Ipow(long x, long y) 
900 {
901   Integer r(x); pow(r, y, r); return r;
902 }
903
904 inline Integer pow(const Integer& x, const Integer& y) 
905 {
906   Integer r; pow(x, y, r); return r;
907 }
908
909
910
911 inline Integer abs(const Integer& x) 
912 {
913   Integer r; abs(x, r); return r;
914 }
915
916 inline Integer operator - (const Integer& x) 
917 {
918   Integer r; negate(x, r); return r;
919 }
920
921 inline Integer operator ~ (const Integer& x) 
922 {
923   Integer r; complement(x, r); return r;
924 }
925
926 inline Integer  atoI(const char* s, int base) 
927 {
928   Integer r; r.rep = atoIntRep(s, base); return r;
929 }
930
931 inline Integer  gcd(const Integer& x, const Integer& y) 
932 {
933   Integer r; r.rep = gcd(x.rep, y.rep); return r;
934 }
935
936 #endif /* !_Integer_h */