#include "Rational.h"
IntType
Gcd1( const IntType & N, const IntType & M )
{
if( N % M == 0 )
return M;
else
return Gcd1( M, N % M );
}
IntType
Gcd( const IntType & M, const IntType & N )
{
if( M > 0 )
return Gcd1( N, M );
else
return Gcd1( N, -M );
}
void
Rational::FixSigns( )
{
if( Denom < 0 )
{
Denom = -Denom;
Numer = -Numer;
}
}
void
Rational::Reduce( )
{
IntType D = 1;
if( Denom != 0 && Numer != 0 )
D = Gcd( Numer, Denom );
if( D > 1 )
{
Numer /= D;
Denom /= D;
}
}
const Rational &
Rational::operator=( const Rational & Rhs )
{
if( this != &Rhs )
{
Numer = Rhs.Numer;
Denom = Rhs.Denom;
}
return *this;
}
const Rational &
Rational::operator+=( const Rational & Rhs )
{
Numer = Numer * Rhs.Denom + Rhs.Numer * Denom;
Denom = Denom * Rhs.Denom;
Reduce( );
return *this;
}
const Rational &
Rational::operator-=( const Rational & Rhs )
{
Numer = Numer * Rhs.Denom - Rhs.Numer * Denom;
Denom = Denom * Rhs.Denom;
Reduce( );
return *this;
}
const Rational &
Rational::operator*=( const Rational & Rhs )
{
IntType NewNumer = Numer * Rhs.Numer;
IntType NewDenom = Denom * Rhs.Denom;
Numer = NewNumer;
Denom = NewDenom;
Reduce( );
return *this;
}
const Rational &
Rational::operator/=( const Rational & Rhs )
{
IntType NewNumer = Numer * Rhs.Denom;
IntType NewDenom = Denom * Rhs.Numer;
Numer = NewNumer;
Denom = NewDenom;
FixSigns( );
Reduce( );
return *this;
}
Rational
Rational::operator+( const Rational & Rhs ) const
{
Rational Answer( *this );
Answer += Rhs;
return Answer;
}
Rational
Rational::operator-( const Rational & Rhs ) const
{
Rational Answer( *this );
Answer -= Rhs;
return Answer;
}
Rational
Rational::operator*( const Rational & Rhs ) const
{
Rational Answer( *this );
Answer *= Rhs;
return Answer;
}
Rational
Rational::operator/( const Rational & Rhs ) const
{
Rational Answer( *this );
Answer /= Rhs;
return Answer;
}
int
Rational::operator==( const Rational & Rhs ) const
{
return Numer * Rhs.Denom == Denom * Rhs.Numer;
}
int
Rational::operator!=( const Rational & Rhs ) const
{
return Numer * Rhs.Denom != Denom * Rhs.Numer;
}
int
Rational::operator<=( const Rational & Rhs ) const
{
return Numer * Rhs.Denom <= Denom * Rhs.Numer;
}
int
Rational::operator<( const Rational & Rhs ) const
{
return Numer * Rhs.Denom < Denom * Rhs.Numer;
}
int
Rational::operator>=( const Rational & Rhs ) const
{
return Numer * Rhs.Denom >= Denom * Rhs.Numer;
}
int
Rational::operator>( const Rational & Rhs ) const
{
return Numer * Rhs.Denom > Denom * Rhs.Numer;
}
const Rational &
Rational::operator++( )
{
Numer += Denom;
return *this;
}
Rational
Rational::operator++( int )
{
Rational Tmp = *this;
Numer += Denom;
return Tmp;
}
const Rational &
Rational::operator--( )
{
Numer -= Denom;
return *this;
}
Rational
Rational::operator--( int )
{
Rational Tmp = *this;
Numer -= Denom;
return Tmp;
}
int
Rational::operator!( ) const
{
return !Numer;
}
const Rational &
Rational::operator+( ) const
{
return *this;
}
Rational
Rational::operator-( ) const
{
return Rational( -Numer, Denom );
}
istream &
operator>>( istream & In, Rational & Value )
{
In >> Value.Numer;
char Ch = ' ';
In.get( Ch );
if( Ch == '/' )
{
In >> Value.Denom;
Value.FixSigns( );
Value.Reduce( );
}
else
{
Value.Denom = 1;
In.putback( Ch );
}
return In;
}
ostream &
operator<<( ostream & Out, const Rational & Value )
{
if( Value.Denom != 0 )
{
Out << Value.Numer;
if( Value.Denom != 1 )
Out << '/' << Value.Denom;
return Out;
}
if( Value.Numer == 0 )
Out << "indeterminate";
else
{
if( Value.Numer < 0 )
Out << '-';
Out << "infinity";
}
return Out;
}