#ifndef RATIONAL_H
#define RATIONAL_H
#include<iostream>
using namespace std;
#define NEGATIVE -1
#define POSITIVE 1
class Rational
{
friend ostream& operator<<(ostream& s,const Rational&);
private:
long _a,_b;
int _sgn;//Sign of No
void simplify(Rational& num)
{
long a=num.GetNum();
long b=num.GetDenom();
long d=gcd(a,b);
a/=d;
b/=d;
_a=a;
_b=b;
}
long gcd(long a,long b)
{
long c=0;
if(b!=0)
{
do
{
c=a%b;
a=b;
b=c;
if(b==0) break;
}
while(1);
}
else
{
throw "Division by Zero";
}
return a;
}
public:
Rational(long num=0,long denom=1)
{
if(num<0 || denom<0)
{
_sgn=NEGATIVE;
}
else
{
_sgn=POSITIVE;
}
_a=(num<0)?-num:num;
_b=(denom<0)?-denom:denom;
simplify(*this);
}
void Assign(long num,long den)
{
if(num<0 || den<0)
{
_sgn=NEGATIVE;
}
else
{
_sgn=POSITIVE;
}
_a=(num<0)?-num:num;
_b=(den<0)?-den:den;
simplify(*this);
}
long GetNum()
{
return _a;
}
long GetDenom()
{
return _b;
}
int GetSgn()
{
return _sgn;
}
Rational operator=(Rational& num)
{
_a=num.GetNum();
_b=num.GetDenom();
simplify(*this);
return (*this);
}
Rational operator=(long num)
{
if(num<0)
{
_sgn=NEGATIVE;
}
else
{
_sgn=POSITIVE;
}
_a=(num<0)?-num:num;
_b=1;
return (*this);
}
Rational operator+(Rational& num)
{
long c=num.GetNum();
long d=num.GetDenom();
int s=num.GetSgn();
long numerator=(GetSgn()*GetNum()*d)+(s*GetDenom()*c);
long denomerator=GetDenom()*d;
/*
a c ad+bc
- + - = -------
b d bd
*/
return Rational(numerator,denomerator);
}
bool operator==(Rational& num)
{
long a=GetNum();
long b=GetDenom();
int sgn1=GetSgn();
a*=sgn1;
long c=num.GetNum();
long d=num.GetDenom();
int sgn2=num.GetSgn();
c*=sgn2;
bool bRet=(((float)a/b)==((float)c/d));
return bRet;
}
};
ostream& operator<<(ostream& s,Rational& num)
{
if(num.GetDenom()!=1)
{
s<<((num.GetSgn()==NEGATIVE)?"-":"")<<num.GetNum()<<"/"<<num.GetDenom();
}
else
{
s<<((num.GetSgn()==NEGATIVE)?"-":"")<<num.GetDenom();
}
return s;
}
#endif