/****************************************************************** * Core Library Version 1.6, June 2003 * Copyright (c) 1995-2003 Exact Computation Project * * File: BigRat.h * * Synopsis: a wrapper class of mpq in GMP * * Written by * Chee Yap * Zilin Du * * WWW URL: http://cs.nyu.edu/exact/ * Email: exact@cs.nyu.edu * * $Id$ *****************************************************************/ #ifndef CORE_BIGRAT_H #define CORE_BIGRAT_H #include CORE_BEGIN_NAMESPACE /// \class BigRat BigRat.h /// \brief BigRat is a wrapper class of mpq in GMP class BigRat { private: mpq_t mp; public: /// \name Constructors and Destructor //@{ /// default constructor BigRat() { mpq_init(mp); } /// copy constructor BigRat(const BigRat& q) { mpq_init(mp); mpq_set(mp, q.mpq()); } /// constructor for signed char BigRat(signed char c) { mpq_init(mp); mpq_set_si(mp, c, 1); } /// constructor for unsigned char BigRat(unsigned char c) { mpq_init(mp); mpq_set_ui(mp, c, 1); } /// constructor for signed int BigRat(signed int i) { mpq_init(mp); mpq_set_si(mp, i, 1); } /// constructor for unsigned int BigRat(unsigned int i) { mpq_init(mp); mpq_set_ui(mp, i, 1); } /// constructor for signed short int BigRat(signed short int s) { mpq_init(mp); mpq_set_si(mp, s, 1); } /// constructor for unsigned short int BigRat(unsigned short int s) { mpq_init(mp); mpq_set_ui(mp, s, 1); } /// constructor for signed long int BigRat(signed long int l) { mpq_init(mp); mpq_set_si(mp, l, 1); } /// constructor for unsigned long int BigRat(unsigned long int l) { mpq_init(mp); mpq_set_ui(mp, l, 1); } /// constructor for float BigRat(float f) { mpq_init(mp); mpq_set_d(mp, f); } /// constructor for double BigRat(double d) { mpq_init(mp); mpq_set_d(mp, d); } /// constructor for const char* with base BigRat(const char *s, int base = 0) { mpq_init(mp); mpq_set_str(mp, s, base); } /// constructor for std::string with base BigRat(const std::string &s, int base = 0) { mpq_init(mp); mpq_set_str(mp, s.c_str(), base); } /// constructor for mpq_srcptr explicit BigRat(mpq_srcptr q) { mpq_init(mp); mpq_set(mp, q); } /// constructor for BigInt BigRat(const BigInt& z) { mpq_init(mp); mpq_set_z(mp, z.mpz()); } /// constructor for two BigInts BigRat(const BigInt& n, const BigInt& d) { mpq_init(mp); mpz_set(mpq_numref(mp), n.mpz()); mpz_set(mpq_denref(mp), d.mpz()); mpq_canonicalize(mp); } /// destructor ~BigRat() { mpq_clear(mp); } //@} /// \name Assignment Operators //@{ /// = operator for BigRat BigRat& operator= (const BigRat& q) { if (&q != this) mpq_set(mp, q.mpq()); return *this; } /// = operator for signed char BigRat& operator= (signed char c) { mpq_set_si(mp, c, 1); return *this; } /// = operator for unsigned char BigRat& operator= (unsigned char c) { mpq_set_ui(mp, c, 1); return *this; } /// = operator for signed int BigRat& operator= (signed int i) { mpq_set_si(mp, i, 1); return *this; } /// = operator for unsigned int BigRat& operator= (unsigned int i) { mpq_set_ui(mp, i, 1); return *this; } /// = operator for signed short int BigRat& operator= (signed short int s) { mpq_set_si(mp, s, 1); return *this; } /// = operator for unsigned short int BigRat& operator= (unsigned short int s) { mpq_set_ui(mp, s, 1); return *this; } /// = operator for signed long int BigRat& operator= (signed long int l) { mpq_set_si(mp, l, 1); return *this; } /// = operator for unsigned long int BigRat& operator= (unsigned long int l) { mpq_set_ui(mp, l, 1); return *this; } /// = operator for float BigRat& operator= (float f) { mpq_set_d(mp, f); return *this; } /// = operator for double BigRat& operator= (double d) { mpq_set_d(mp, d); return *this; } /// = operator for const char* BigRat& operator= (const char *s) { mpq_set_str(mp, s, 0); return *this; } /// = operator for std::string BigRat& operator= (const std::string &s) { mpq_set_str(mp, s.c_str(), 0); return *this; } //@} /// \name Compound Assignment Operators //@{ /// operator+= BigRat& operator+= (const BigRat& q) { mpq_add(mp, mp, q.mpq()); return *this; } /// operator-= BigRat& operator-= (const BigRat& q) { mpq_sub(mp, mp, q.mpq()); return *this; } /// operator*= BigRat& operator*= (const BigRat& q) { mpq_mul(mp, mp, q.mpq()); return *this; } /// operator/= BigRat& operator/= (const BigRat& q) { mpq_div(mp, mp, q.mpq()); return *this; } /// operator<<= BigRat& operator<<= (long int l) { (l>=0)?mpq_mul_2exp(mp, mp, l):mpq_div_2exp(mp, mp, -l); return *this; } /// operator>>= BigRat& operator>>= (long int l) { (l>=0)?mpq_div_2exp(mp, mp, l):mpq_mul_2exp(mp, mp, -l); return *this; } //@} /// \name Unary Minus, Increment, and Decrement Operators //@{ /// unary minus BigRat operator- () const { BigRat c; mpq_neg(c.mpq(), mp); return c; } /// left increment operator (++i) BigRat& operator++ () { mpz_add(mpq_numref(mp), mpq_numref(mp), mpq_denref(mp)); return *this; } /// left decrement operator (--i) BigRat& operator-- () { mpz_sub(mpq_numref(mp), mpq_numref(mp), mpq_denref(mp)); return *this; } /// right increment operator (i++) BigRat operator++ (int) { BigRat a(*this); mpz_add(mpq_numref(mp), mpq_numref(mp), mpq_denref(mp)); return a; } /// right deccrement operator (i--) BigRat operator-- (int) { BigRat a(*this); mpz_add(mpq_numref(mp), mpq_numref(mp), mpq_denref(mp)); return a; } //@} /// \name String Conversion Functions //@{ /// set value from const char* /** * \returns 0 if the entire string is a valid number in base base. * Otherwise it returns -1 */ int fromString(const char* s, int base = 0) { return mpq_set_str(mp, s, base); } /// convert to std::string std::string toString(int base = 10) const { __gmp_alloc_cstring t(mpq_get_str(0, base, mp)); return std::string(t.str);} //@} /// \name Conversion Functions //@{ /// return double value double doubleValue() const { return mpq_get_d(mp); } /// return BigInt value BigInt BigIntValue() const { return numerator()/denominator(); } //@} /// \name File I/O Functions //@{ /// read from file void readFromFile(std::istream& in, long maxLength = 0); /// write to file void writeToFile(std::ostream& in, int base=10, int charsPerLine=80) const; //@} /// \name Helper Functions //@{ /// Canonicalize void canonicalize() { mpq_canonicalize(mp); } /// return sign int sign() const { return mpq_sgn(mp); } /// return absolute value BigRat abs() const { BigRat c; mpq_abs(c.mpq(), mp); return c; } /// return negation value BigRat neg() const { BigRat c; mpq_neg(c.mpq(), mp); return c; } /// negate value void negate() { mpq_neg(mp, mp); } /// comparision function int cmp(const BigRat& q) const { return mpq_cmp(mp, q.mpq()); } /// return the numerater (const) const BigInt numerator() const { return BigInt(mpq_numref(mp)); } /// return the numerater BigInt numerator() { return BigInt(mpq_numref(mp)); } /// return the denominator (const) const BigInt denominator() const { return BigInt(mpq_denref(mp)); } /// return the denominator BigInt denominator() { return BigInt(mpq_denref(mp)); } /// return mpq pointer (const) (!!internal use!!) mpq_srcptr mpq() const { return mp; } /// return mpq pointer (!!internal use!!) mpq_ptr mpq() { return mp; } /// return mpz pointer of numerator (const) (!!internal use!!) mpz_srcptr num_mpz() const { return mpq_numref(mp); } /// return mpz pointer of numerator (!!internal use!!) mpz_ptr num_mpz() { return mpq_numref(mp); } /// return mpz pointer of denominator (const) (!!internal use!!) mpz_srcptr den_mpz() const { return mpq_denref(mp); } /// return mpz pointer of denominator (!!internal use!!) mpz_ptr den_mpz() { return mpq_denref(mp); } //@} }; /// IO stream operator << inline std::ostream& operator<<(std::ostream& o, const BigRat& a) { return o << a.toString(); } /// IO stream operator >> inline std::istream& operator>>(std::istream& i, BigRat& a) { return ::operator>>(i, a.mpq()); } /// operator+ inline BigRat operator+ (const BigRat& a, const BigRat& b) { BigRat r(a); r += b; return r; } /// operator- inline BigRat operator- (const BigRat& a, const BigRat& b) { BigRat r(a); r -= b; return r; } /// operator* inline BigRat operator* (const BigRat& a, const BigRat& b) { BigRat r(a); r *= b; return r; } /// operator/ inline BigRat operator/ (const BigRat& a, const BigRat& b) { BigRat r(a); r /= b; return r; } /// operator>> inline BigRat operator>> (const BigRat& a, long int l) { BigRat r(a); r >>= l; return r; } /// operator<< inline BigRat operator<< (const BigRat& a, long int l) { BigRat r(a); r <<= l; return r; } /// operator== inline bool operator== (const BigRat& a, const BigRat& b) { return a.cmp(b) == 0; } /// operator!= inline bool operator!= (const BigRat& a, const BigRat& b) { return a.cmp(b) != 0; } /// operator>= inline bool operator>= (const BigRat& a, const BigRat& b) { return a.cmp(b) >= 0; } /// operator> inline bool operator> (const BigRat& a, const BigRat& b) { return a.cmp(b) > 0; } /// operator<= inline bool operator<= (const BigRat& a, const BigRat& b) { return a.cmp(b) <= 0; } /// operator< inline bool operator< (const BigRat& a, const BigRat& b) { return a.cmp(b) < 0; } /// sign inline int sign(const BigRat& a) { return a.sign(); } /// abs inline BigRat abs(const BigRat& a) { return a.abs(); } /// neg inline BigRat neg(const BigRat& a) { return a.neg(); } /// cmp inline int cmp(const BigRat& a, const BigRat& b) { return a.cmp(b); } CORE_END_NAMESPACE #endif // CORE_BIGRAT_H