00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 #ifndef _cvc3__rational_h_
00030 #define _cvc3__rational_h_
00031 
00032 
00033 
00034 
00035 #include <vector>
00036 #include "debug.h"
00037 
00038 
00039 namespace CVC3 {
00040 
00041   class CVC_DLL Rational {
00042   private:
00043     class Impl;
00044     Impl *d_n;
00045     
00046 #ifdef _DEBUG_RATIONAL_
00047     
00048     
00049     int& getCreated() {
00050       static int num_created = 0;
00051       return(num_created);
00052     }
00053       
00054     int& getDeleted() {
00055       static int num_deleted = 0;
00056       return(num_deleted);
00057     }
00058       
00059     void printStats();
00060 #endif
00061     
00062     Rational(const Impl& t);
00063 
00064   public:
00065     
00066     Rational();
00067     
00068     Rational(const Rational &n);
00069     Rational(int n, int d = 1);
00070     Rational(const char* n, int base = 10);
00071     Rational(const std::string& n, int base = 10);
00072     Rational(const char* n, const char* d, int base = 10);
00073     Rational(const std::string& n, const std::string& d, int base = 10);
00074     
00075     ~Rational();
00076 
00077     
00078     Rational& operator=(const Rational& n);
00079 
00080     std::string toString(int base = 10) const;
00081 
00082     
00083     size_t hash() const;
00084 
00085     friend bool operator==(const Rational &n1, const Rational &n2);
00086     friend bool operator<(const Rational &n1, const Rational &n2);
00087     friend bool operator<=(const Rational &n1, const Rational &n2);
00088     friend bool operator>(const Rational &n1, const Rational &n2);
00089     friend bool operator>=(const Rational &n1, const Rational &n2);
00090     friend bool operator!=(const Rational &n1, const Rational &n2);
00091     friend Rational operator+(const Rational &n1, const Rational &n2);
00092     friend Rational operator-(const Rational &n1, const Rational &n2);
00093     friend Rational operator*(const Rational &n1, const Rational &n2);
00094     friend Rational operator/(const Rational &n1, const Rational &n2);
00095     
00096     friend Rational operator%(const Rational &n1, const Rational &n2);
00097 
00098     
00099     Rational operator-() const;
00100     Rational &operator+=(const Rational &n2);
00101     Rational &operator-=(const Rational &n2);
00102     Rational &operator*=(const Rational &n2);
00103     Rational &operator/=(const Rational &n2);
00104 
00105     const Rational& operator++() { *this = (*this)+1; return *this; }
00106 
00107     Rational operator++(int) { Rational x(*this); *this = x+1; return x; }
00108 
00109     const Rational& operator--() { *this = (*this)-1; return *this; }
00110 
00111     Rational operator--(int) { Rational x(*this); *this = x-1; return x; }
00112 
00113     
00114     Rational getNumerator() const;
00115     Rational getDenominator() const;
00116 
00117     
00118     bool isInteger() const;
00119     
00120     int getInt() const;
00121     
00122     bool isUnsigned() const { return (isInteger() && (*this) >= 0); }
00123     
00124     unsigned int getUnsigned() const;
00125 
00126     friend std::ostream &operator<<(std::ostream &os, const Rational &n);
00127 
00128     
00129 
00130 
00131     friend Rational gcd(const Rational &x, const Rational &y);
00132     friend Rational gcd(const std::vector<Rational> &v);
00133     friend Rational lcm(const Rational &x, const Rational &y);
00134     friend Rational lcm(const std::vector<Rational> &v);
00135 
00136     friend Rational abs(const Rational &x);
00137 
00138 
00139     friend Rational floor(const Rational &x);
00140 
00141     friend Rational ceil(const Rational &x);
00142 
00143     friend Rational mod(const Rational &x, const Rational &y);
00144 
00145     
00146     void print() const;
00147 
00148   }; 
00149 
00150 
00151   inline Rational pow(Rational pow, const Rational& base) {
00152     DebugAssert(pow.isInteger(), "pow("+pow.toString()
00153     +", "+base.toString()+")");
00154     FatalAssert(base != 0 || pow >= 0, "Attempt to divide by zero");
00155     bool neg(pow < 0);
00156     if(neg) pow = -pow;
00157     Rational res(1);
00158     for(; pow > 0; --pow) res *= base;
00159     if(neg) res = 1/res;
00160     return res;
00161   }
00162 
00163   
00164   
00165   
00166   inline Rational newRational(int n, int d = 1) { return Rational(n, d); }
00167   inline Rational newRational(const char* n, int base = 10)
00168     { return Rational(n, base); }
00169   inline Rational newRational(const std::string& n, int base = 10)
00170     { return Rational(n, base); }
00171   inline Rational newRational(const char* n, const char* d, int base = 10)
00172     { return Rational(n, d, base); }
00173   inline Rational newRational(const std::string& n, const std::string& d,
00174             int base = 10)
00175     { return Rational(n, d, base); }
00176     
00177   
00178   void printRational(const Rational &x);
00179 
00180 } 
00181 
00182 #endif