#ifndef RATIONAL_H
#define RATIONAL_H
#include <iostream>
using namespace std;
template<class T>
class Rational {
public:
Rational() : num(0), den(1) {}
Rational(T n, T d = 1);
Rational(const Rational<T>& rhs) : num(rhs.num), den(rhs.den) {}
~Rational(void) {}
T numerator(void) const { return num; }
T denominator(void) const { return den; }
Rational<T>& operator=(const Rational<T>& rhs);
Rational<T>& operator=(T rhs);
Rational<T> operator+(void) const { return *this; }
Rational<T> operator-(void) const { return Rational<T>(-num, den); }
Rational<T> invert(void) const { return Rational<T>(den, num); }
const Rational<T>& operator+=(const Rational<T>& rhs);
const Rational<T>& operator-=(const Rational<T>& rhs);
const Rational<T>& operator*=(const Rational<T>& rhs);
const Rational<T>& operator/=(const Rational<T>& rhs);
const Rational<T>& operator+=(T rhs);
const Rational<T>& operator-=(T rhs);
const Rational<T>& operator*=(T rhs);
const Rational<T>& operator/=(T rhs);
const Rational<T>& operator++();
const Rational<T> operator++(int);
const Rational<T>& operator--();
const Rational<T> operator--(int);
private:
T num;
T den;
T gcd(T, T);
};
template<class T>
inline Rational<T>& Rational<T>::operator=(const Rational<T>& rhs) {
num = rhs.num;
den = rhs.den;
return *this;
}
template<class T>
inline Rational<T>& Rational<T>::operator=(T rhs) {
num = rhs;
den = 1;
return *this;
}
template<class T>
inline double toDouble (const Rational<T>& r) {
return double(r.numerator())/r.denominator();
}
template<class T>
inline T trunc(const Rational<T>& r) {
return r.numerator() / r.denominator();
}
template<class T>
inline T floor(const Rational<T>& r) {
T q = r.numerator() / r.denominator();
return (r.numerator() < 0 && r.denominator() != 1) ? --q : q;
}
template<class T>
inline T ceil(const Rational<T>& r) {
T q = r.numerator() / r.denominator();
return (r.numerator() >= 0 && r.denominator() != 1) ? ++q : q;
}
template<class T>
Rational<T> toRational(double x, int iterations = 5);
template<class T>
const Rational<T> operator+(const Rational<T>& lhs, const Rational<T>& rhs);
template<class T>
const Rational<T> operator-(const Rational<T>& lhs, const Rational<T>& rhs);
template<class T>
const Rational<T> operator*(const Rational<T>& lhs, const Rational<T>& rhs);
template<class T>
const Rational<T> operator/(const Rational<T>& lhs, const Rational<T>& rhs);
template<class T>
Rational<T> rabs(const Rational<T>& rhs);
template<class T>
bool operator==(const Rational<T>& lhs, const Rational<T>& rhs);
template<class T>
bool operator!=(const Rational<T>& lhs, const Rational<T>& rhs);
template<class T>
bool operator<=(const Rational<T>& lhs, const Rational<T>& rhs);
template<class T>
bool operator>=(const Rational<T>& lhs, const Rational<T>& rhs);
template<class T>
bool operator<(const Rational<T>& lhs, const Rational<T>& rhs);
template<class T>
bool operator>(const Rational<T>& lhs, const Rational<T>& rhs);
template<class T>
ostream& operator<< (ostream& ostr, const Rational<T>& r);
template<class T>
istream& operator>> (istream& istr, Rational<T>& r);
#include "Rational.cpp"
#endif