00001
00002 #ifndef _Rational_h
00003 #define _Rational_h
00004
00005
00006 #include "../include/Integer.h"
00007
00008 class Rational
00009 {
00010 protected:
00011 Integer num;
00012 Integer den;
00013
00014 void normalize();
00015
00016 public:
00017 Rational();
00018 Rational(double);
00019 Rational(int n);
00020 Rational(long n);
00021 Rational(int n, int d);
00022 Rational(long n, long d);
00023 Rational(long n, unsigned long d);
00024 Rational(unsigned long n, long d);
00025 Rational(unsigned long n, unsigned long d);
00026 Rational(const Integer& n);
00027 Rational(const Integer& n, const Integer& d);
00028 Rational(const Rational&);
00029
00030 ~Rational();
00031
00032 Rational& operator = (const Rational& y);
00033
00034 inline int operator == (const Rational& x ) { return compare(num, x.num) == 0 && compare(den, x.den) == 0; }
00035 inline int operator != (const Rational& x ) { return compare(num, x.num) != 0 || compare(den, x.den) != 0; }
00036 friend int operator < (const Rational& x, const Rational& y);
00037 friend int operator <= (const Rational& x, const Rational& y);
00038 friend int operator > (const Rational& x, const Rational& y);
00039 friend int operator >= (const Rational& x, const Rational& y);
00040
00041 friend Rational operator + (const Rational& x, const Rational& y);
00042 friend Rational operator - (const Rational& x, const Rational& y);
00043 friend Rational operator * (const Rational& x, const Rational& y);
00044 friend Rational operator / (const Rational& x, const Rational& y);
00045
00046 Rational& operator += (const Rational& y);
00047 Rational& operator -= (const Rational& y);
00048 Rational& operator *= (const Rational& y);
00049 Rational& operator /= (const Rational& y);
00050
00051 friend Rational operator - (const Rational& x);
00052
00053
00054
00055
00056
00057 void negate();
00058 void invert();
00059
00060 friend int sign(const Rational& x);
00061 friend Rational abs(const Rational& x);
00062 friend Rational sqr(const Rational& x);
00063 friend Rational pow(const Rational& x, long y);
00064 friend Rational pow(const Rational& x, const Integer& y);
00065 const Integer& numerator() const;
00066 const Integer& denominator() const;
00067
00068
00069
00070 operator double() const;
00071 friend Integer floor(const Rational& x);
00072 friend Integer ceil(const Rational& x);
00073 friend Integer trunc(const Rational& x);
00074 friend Integer round(const Rational& x);
00075
00076 friend istream& operator >> (istream& s, Rational& y);
00077 friend ostream& operator << (ostream& s, const Rational& y);
00078
00079 int fits_in_float() const;
00080 int fits_in_double() const;
00081
00082
00083
00084 friend int compare(const Rational& x, const Rational& y);
00085 friend void add(const Rational& x, const Rational& y, Rational& dest);
00086 friend void sub(const Rational& x, const Rational& y, Rational& dest);
00087 friend void mul(const Rational& x, const Rational& y, Rational& dest);
00088 friend void div(const Rational& x, const Rational& y, Rational& dest);
00089
00090
00091
00092 void error(const char* msg) const;
00093 int OK() const;
00094
00095 };
00096
00097 typedef Rational RatTmp;
00098
00099 inline Rational::Rational() : num(&_ZeroRep), den(&_OneRep) {}
00100 inline Rational::~Rational() {}
00101
00102 inline Rational::Rational(const Rational& y) :num(y.num), den(y.den) {}
00103
00104 inline Rational::Rational(const Integer& n) :num(n), den(&_OneRep) {}
00105
00106 inline Rational::Rational(const Integer& n, const Integer& d) :num(n),den(d)
00107 {
00108 normalize();
00109 }
00110
00111 inline Rational::Rational(long n) :num(n), den(&_OneRep) { }
00112
00113 inline Rational::Rational(int n) :num(n), den(&_OneRep) { }
00114
00115 inline Rational::Rational(long n, long d) :num(n), den(d) { normalize(); }
00116 inline Rational::Rational(int n, int d) :num(n), den(d) { normalize(); }
00117 inline Rational::Rational(long n, unsigned long d) :num(n), den(d)
00118 {
00119 normalize();
00120 }
00121 inline Rational::Rational(unsigned long n, long d) :num(n), den(d)
00122 {
00123 normalize();
00124 }
00125 inline Rational::Rational(unsigned long n, unsigned long d) :num(n), den(d)
00126 {
00127 normalize();
00128 }
00129
00130 inline Rational& Rational::operator = (const Rational& y)
00131 {
00132 num = y.num; den = y.den;
00133 return *this;
00134 }
00135
00136
00137 inline int operator < (const Rational& x, const Rational& y)
00138 {
00139 return compare(x, y) < 0;
00140 }
00141
00142 inline int operator <= (const Rational& x, const Rational& y)
00143 {
00144 return compare(x, y) <= 0;
00145 }
00146
00147 inline int operator > (const Rational& x, const Rational& y)
00148 {
00149 return compare(x, y) > 0;
00150 }
00151
00152 inline int operator >= (const Rational& x, const Rational& y)
00153 {
00154 return compare(x, y) >= 0;
00155 }
00156
00157 inline int sign(const Rational& x)
00158 {
00159 return sign(x.num);
00160 }
00161
00162 inline void Rational::negate()
00163 {
00164 num.negate1();
00165 }
00166
00167
00168 inline Rational& Rational::operator += (const Rational& y)
00169 {
00170 add(*this, y, *this);
00171 return *this;
00172 }
00173
00174 inline Rational& Rational::operator -= (const Rational& y)
00175 {
00176 sub(*this, y, *this);
00177 return *this;
00178 }
00179
00180 inline Rational& Rational::operator *= (const Rational& y)
00181 {
00182 mul(*this, y, *this);
00183 return *this;
00184 }
00185
00186 inline Rational& Rational::operator /= (const Rational& y)
00187 {
00188 div(*this, y, *this);
00189 return *this;
00190 }
00191
00192 inline const Integer& Rational::numerator() const { return num; }
00193 inline const Integer& Rational::denominator() const { return den; }
00194 inline Rational::operator double() const { return ratio(num, den); }
00195
00196 inline Rational operator + (const Rational& x, const Rational& y)
00197 {
00198 Rational r; add(x, y, r); return r;
00199 }
00200
00201 inline Rational operator - (const Rational& x, const Rational& y)
00202 {
00203 Rational r; sub(x, y, r); return r;
00204 }
00205
00206 inline Rational operator * (const Rational& x, const Rational& y)
00207 {
00208 Rational r; mul(x, y, r); return r;
00209 }
00210
00211 inline Rational operator / (const Rational& x, const Rational& y)
00212 {
00213 Rational r; div(x, y, r); return r;
00214 }
00215
00216 #endif