// // $Source: /cvsroot/gambit/gambit/sources/libgambit/integer.h,v $ // $Date: 2006/01/24 21:33:36 $ // $Revision: 1.6 $ // // DESCRIPTION: // Interface to an arbitrary-length integer class // // This file is part of Gambit // Modifications copyright (c) 2002, The Gambit Project // // The original copyright and license are included below. // // This may look like C code, but it is really -*- C++ -*- /* Copyright (C) 1988 Free Software Foundation written by Doug Lea (dl@rocky.oswego.edu) This file is part of the GNU C++ Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef LIBGAMBIT_INTEGER_H #if defined(__GNUG__) && !defined(__APPLE_CC__) #pragma interface #endif #define LIBGAMBIT_INTEGER_H #include namespace Gambit { struct IntegerRep // internal Integer representations { unsigned short len; // current length unsigned short sz; // allocated space (0 means static). short sgn; // 1 means >= 0; 0 means < 0 unsigned short s[1]; // represented as ushort array starting here }; // True if REP is staticly (or manually) allocated, // and should not be deleted by an Integer destructor. #define STATIC_IntegerRep(rep) ((rep)->sz==0) extern IntegerRep* Ialloc(IntegerRep*, const unsigned short *, int, int, int); extern IntegerRep* Icalloc(IntegerRep*, int); extern IntegerRep* Icopy_ulong(IntegerRep*, unsigned long); extern IntegerRep* Icopy_long(IntegerRep*, long); extern IntegerRep* Icopy(IntegerRep*, const IntegerRep*); extern IntegerRep* Iresize(IntegerRep*, int); extern IntegerRep* add(const IntegerRep*, int, const IntegerRep*, int, IntegerRep*); extern IntegerRep* add(const IntegerRep*, int, long, IntegerRep*); extern IntegerRep* multiply(const IntegerRep*, const IntegerRep*, IntegerRep*); extern IntegerRep* multiply(const IntegerRep*, long, IntegerRep*); extern IntegerRep* lshift(const IntegerRep*, long, IntegerRep*); extern IntegerRep* lshift(const IntegerRep*, const IntegerRep*, int, IntegerRep*); extern IntegerRep* bitop(const IntegerRep*, const IntegerRep*, IntegerRep*, char); extern IntegerRep* bitop(const IntegerRep*, long, IntegerRep*, char); extern IntegerRep* power(const IntegerRep*, long, IntegerRep*); extern IntegerRep* div(const IntegerRep*, const IntegerRep*, IntegerRep*); extern IntegerRep* mod(const IntegerRep*, const IntegerRep*, IntegerRep*); extern IntegerRep* div(const IntegerRep*, long, IntegerRep*); extern IntegerRep* mod(const IntegerRep*, long, IntegerRep*); extern IntegerRep* Compl(const IntegerRep*, IntegerRep*); extern IntegerRep* abs(const IntegerRep*, IntegerRep*); extern IntegerRep* negate(const IntegerRep*, IntegerRep*); extern IntegerRep* gcd(const IntegerRep*, const IntegerRep* y); extern int compare(const IntegerRep*, const IntegerRep*); extern int compare(const IntegerRep*, long); extern int ucompare(const IntegerRep*, const IntegerRep*); extern int ucompare(const IntegerRep*, long); extern std::string Itoa(const IntegerRep* x, int base = 10, int width = 0); extern std::string cvtItoa(const IntegerRep* x, std::string fmt, int& fmtlen, int base, int showbase, int width, int align_right, char fillchar, char Xcase, int showpos); extern IntegerRep* atoIntegerRep(const char* s, int base = 10); extern long Itolong(const IntegerRep*); extern double Itodouble(const IntegerRep*); extern int Iislong(const IntegerRep*); extern int Iisdouble(const IntegerRep*); extern long lg(const IntegerRep*); class Integer { protected: IntegerRep *rep; public: /// @name Lifecycle //@{ Integer(void); Integer(int); Integer(long); Integer(unsigned long); Integer(IntegerRep *); Integer(const Integer &); ~Integer(); Integer &operator=(const Integer &); Integer &operator=(long); //@} /// @name Unary operations on self //@{ void operator ++ (); void operator -- (); void negate(); // negate in-place void abs(); // absolute-value in-place //@{ /// @name Comparison operators //@{ bool operator==(const Integer &) const; bool operator==(long) const; bool operator!=(const Integer &) const; bool operator!=(long) const; bool operator< (const Integer &) const; bool operator< (long) const; bool operator<=(const Integer &) const; bool operator<=(long) const; bool operator> (const Integer &) const; bool operator> (long) const; bool operator>=(const Integer &) const; bool operator>=(long) const; //@} /// @name Assignment-based operations //@{ Integer &operator+=(const Integer &); Integer &operator-=(const Integer &); Integer &operator*=(const Integer &); Integer &operator/=(const Integer &); Integer &operator%=(const Integer &); Integer &operator<<=(const Integer &); Integer &operator>>=(const Integer &); Integer &operator+=(long); Integer &operator-=(long); Integer &operator*=(long); Integer &operator/=(long); Integer &operator%=(long); Integer &operator<<=(long); Integer &operator>>=(long); //@} /// @name Operator overloading //@{ Integer operator-(void) const; Integer operator+(const Integer &) const; Integer operator+(long) const; Integer operator-(const Integer &) const; Integer operator-(long) const; Integer operator*(const Integer &) const; Integer operator*(long) const; Integer operator/(const Integer &) const; Integer operator/(long) const; Integer operator%(const Integer &) const; Integer operator%(long) const; Integer operator<<(const Integer &) const; Integer operator<<(long) const; Integer operator>>(const Integer &) const; Integer operator>>(long) const; //@} // builtin Integer functions that must be friends friend long lg (const Integer&); // floor log base 2 of abs(x) friend double ratio(const Integer& x, const Integer& y); // return x/y as a double friend Integer gcd(const Integer&, const Integer&); friend int even(const Integer&); // true if even friend int odd(const Integer&); // true if odd friend int sign(const Integer&); // returns -1, 0, +1 friend void setbit(Integer& x, long b); // set b'th bit of x friend void clearbit(Integer& x, long b); // clear b'th bit friend int testbit(const Integer& x, long b); // return b'th bit // procedural versions of operators friend void abs(const Integer& x, Integer& dest); friend void negate(const Integer& x, Integer& dest); friend void complement(const Integer& x, Integer& dest); friend int compare(const Integer&, const Integer&); friend int ucompare(const Integer&, const Integer&); friend void add(const Integer& x, const Integer& y, Integer& dest); friend void sub(const Integer& x, const Integer& y, Integer& dest); friend void mul(const Integer& x, const Integer& y, Integer& dest); friend void div(const Integer& x, const Integer& y, Integer& dest); friend void mod(const Integer& x, const Integer& y, Integer& dest); friend void divide(const Integer& x, const Integer& y, Integer& q, Integer& r); friend void lshift(const Integer& x, const Integer& y, Integer& dest); friend void rshift(const Integer& x, const Integer& y, Integer& dest); friend void pow(const Integer& x, const Integer& y, Integer& dest); friend int compare(const Integer&, long); friend int ucompare(const Integer&, long); friend void add(const Integer& x, long y, Integer& dest); friend void sub(const Integer& x, long y, Integer& dest); friend void mul(const Integer& x, long y, Integer& dest); friend void div(const Integer& x, long y, Integer& dest); friend void mod(const Integer& x, long y, Integer& dest); friend void divide(const Integer& x, long y, Integer& q, long& r); friend void lshift(const Integer& x, long y, Integer& dest); friend void rshift(const Integer& x, long y, Integer& dest); friend void pow(const Integer& x, long y, Integer& dest); friend int compare(long, const Integer&); friend int ucompare(long, const Integer&); friend void add(long x, const Integer& y, Integer& dest); friend void sub(long x, const Integer& y, Integer& dest); friend void mul(long x, const Integer& y, Integer& dest); // coercion & conversion int fits_in_long() const { return Iislong(rep); } int fits_in_double() const { return Iisdouble(rep); } long as_long() const { return Itolong(rep); } double as_double() const { return Itodouble(rep); } friend std::string Itoa(const Integer& x, int base = 10, int width = 0); friend Integer atoI(const char* s, int base = 10); friend std::istream &operator>>(std::istream &s, Integer& y); friend std::ostream &operator<<(std::ostream &s, const Integer& y); // error detection int initialized() const; void error(const char* msg) const; int OK() const; }; // (These are declared inline) Integer abs(const Integer&); // absolute value Integer sqr(const Integer&); // square Integer pow(const Integer& x, const Integer& y); Integer pow(const Integer& x, long y); Integer Ipow(long x, long y); // x to the y as Integer extern Integer sqrt(const Integer&); // floor of square root extern Integer lcm(const Integer& x, const Integer& y); // least common mult std::string ToText(const Integer &); } // end namespace Gambit #endif // LIBGAMBIT_INTEGER_H