#include <iostream>

using namespace std;

/*
int nzd( int a, int b )
{
	int t;
	// postaramo se da vazi a>=b
	if( a < b ){
		t = b;
		b = a;
		a = t;
		}
	// odrzavamo a>=b i priblizavamo se resenju
	while( b > 0 ){
		t = b;
		b = a % b;
		a = t;
		}
	// ako b=0, a je resenje
	return a;
}
*/
class Razlomak
{
public:
	explicit Razlomak( int b = 0, int i = 1 )
		: _Brojilac(b),
		  _Imenilac(i)
		{ Koriguj(); }
		
	int Imenilac() const
		{ return _Imenilac; }
	int Brojilac() const 
		{ return _Brojilac; }

	void Promeni( int b, int i )
		{ 
		_Brojilac = b;
		_Imenilac = i; 
		Koriguj();
		}

	void Ispisi( ostream& ostr ) const
		{ ostr << _Brojilac << '/'<< _Imenilac; }

	void Citaj( istream& istr )
		{ 
		char c;
		istr >> _Brojilac >> c >> _Imenilac; 
		if( c != '/' )
			istr.setstate( ios::failbit );
		if( istr )	// ekvivalentno sa: if( istr.good() )
			Koriguj();
		}

	Razlomak operator + ( const Razlomak& y ) const
		{
		return Razlomak(
			Brojilac() * y.Imenilac() + Imenilac() * y.Brojilac(),
			Imenilac() * y.Imenilac()
			);
		}

	Razlomak operator - ( const Razlomak& y ) const
		{
		return Razlomak(
			Brojilac() * y.Imenilac() - Imenilac() * y.Brojilac(),
			Imenilac() * y.Imenilac()
			);
		}

	Razlomak operator * ( const Razlomak& y ) const
		{
		return Razlomak(
			Brojilac() * y.Brojilac(),
			Imenilac() * y.Imenilac()
			);
		}

	Razlomak operator / ( const Razlomak& y ) const
		{
		return Razlomak(
			Brojilac() * y.Imenilac(),
			Imenilac() * y.Brojilac()
			);
		}

	Razlomak operator - () const
		{ return Razlomak( -Brojilac(), Imenilac() ); }

	Razlomak operator ~ () const
		{ return Razlomak( Imenilac(), Brojilac() ); }

	bool operator < ( const Razlomak& x ) const 
		{ return Brojilac() * x.Imenilac() < Imenilac() * x.Brojilac(); }

	bool operator == ( const Razlomak& x ) const
		{ return x.Imenilac() == Imenilac() && x.Brojilac() == Brojilac(); }
/*
	bool operator == ( const Razlomak& x ) const
		{ return !( *this < x ) && !( x < *this ); }
*/

	bool operator > ( const Razlomak& x ) const 
		{ return x < *this; }

	bool operator != ( const Razlomak& x ) const
		{ return !( *this == x ); }

	bool operator >= ( const Razlomak& x ) const
		{ return !( *this < x ); }

	bool operator <= ( const Razlomak& x ) const
		{ return !( *this > x ); }

	Razlomak& operator ++ () 
		{
		_Brojilac += _Imenilac;
		return *this; 
		}

	Razlomak operator ++ ( int ) 
		{
		Razlomak y = *this;
		_Brojilac += _Imenilac;
		return y; 
		}

	Razlomak& operator -- () 
		{
		_Brojilac -= _Imenilac;
		return *this; 
		}

	Razlomak operator -- ( int ) 
		{
		Razlomak y = *this;
		_Brojilac -= _Imenilac;
		return y; 
		}
		
	operator double () const
		{ return _Brojilac/(double)_Imenilac; }

	static int nzd( int a, int b )
		{
		int t;
		// postaramo se da vazi a>=b
		if( a < b ){
			t = b;
			b = a;
			a = t;
			}
		// odrzavamo a>=b i priblizavamo se resenju
		while( b > 0 ){
			t = b;
			b = a % b;
			a = t;
			}
		// ako b=0, a je resenje
		return a;
		}
		
private:
	void Koriguj()
		{
		if( _Imenilac < 0 ){
			_Imenilac = -_Imenilac;
			_Brojilac = -_Brojilac;
			}
		int n = nzd( abs( _Brojilac), _Imenilac );
		if( n > 1 ){
			_Brojilac /= n;
			_Imenilac /= n;
			}
		}

	int _Imenilac;
	int _Brojilac;
};

ostream& operator << ( ostream& ostr, const Razlomak& r )
{
	r.Ispisi(ostr);
	return ostr;
}

istream& operator >> ( istream& istr, Razlomak& r )
{
	r.Citaj(istr);
	return istr;
}

main()
{
	Razlomak a(4,5);
	Razlomak b(3,4);
	
	cout << a << " + " << b << " = " << (a+b) << endl;
	cout << a << " + " << b << " = " << a.operator+(b) << endl;

	cout << a << " - " << b << " = " << (a-b) << endl;
	cout << a << " * " << b << " = " << (a*b) << endl;
	cout << a << " / " << b << " = " << (a/b) << endl;
	
	cout << "-" << a << " = " << (-a) << endl;
	cout << "~" << a << " = " << (~a) << endl;
	cout << ( a + b * b - (~a+a) ) << endl;

	cout << ( a + b == b + a ? "true" : "false" )<< endl;

	// problemi
	cout << ~Razlomak() << endl;
	cout << (Razlomak(3,-4) < Razlomak(2,4)) << endl;

	cout << (a++) << endl;
	cout << a << endl;
	cout << (++a) << endl;
	cout << a << endl;
	
	cout << (double)a << endl;
	
	cout << ( a + 5 ) << endl;
	cout << ( (double)a + 5 ) << endl;
	cout << ( a + Razlomak(5) ) << endl;

/*
	cout << "Upisite razlomak: ";
	cin >> a;
	if( cin )
		cout << "Upisan je razlomak " << a << endl;
	else
		cout << "Nije upisan ispravan razlomak!" << endl;
*/		
/*
	a = Razlomak(14,15);
	cout << a << endl;
	a.Brojilac(5);
	a.Imenilac(7);
	cout << a << endl;
	
	a = Razlomak(14,15);
	cout << a << endl;
	a.Imenilac(7);
	a.Brojilac(5);
	cout << a << endl;
*/
	a = Razlomak(14,15);
	cout << a << endl;
	a.Promeni(5,-10);
	a.Promeni(5,a.Imenilac());
	cout << a << endl;

	cout << Razlomak::nzd(55,22) << endl;
	
	return 0;
}



