// Rascal, the Advanced Scientific CALculator
// Copyright (C) 2001, Sebastian Ritterbusch (Rascal@Ritterbusch.de)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more detauls.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//

#ifndef MFRACTION_HPP_INCLUDED
#define MFRACTION_HPP_INCLUDED

#ifdef RESPECT_RASCAL_USER_STOP_VARIABLE
   #define MF_USER_STOP_CONDITION   && !rascal_user_stop
#else
   #define MF_USER_STOP_CONDITION
#endif


template <class T>
class mfraction
{
   public:  
      T  num,den;

   private:
      T  ggT(void)
      {
         T a(num),b(den),c;
         if(a<0)
            a=-a;
         if(b<0)
            b=-b;
         c=b;
         while(a>0 MF_USER_STOP_CONDITION)
         {
            c=a;
            a=b%a;
            b=c;
         }
         return c;
      }

   public:
      void simplify(void)
      {
         T d(ggT());
         num=num/d;
         den=den/d;    
         if(den<0)
         {
            den=-den;
            num=-num;
         }
     
      }
      
      mfraction(T iNom,T iDen=T(1)) : num(iNom),den(iDen) { simplify(); }
};

template<class T>
mfraction<T> operator-(const mfraction<T> & a)
{
   return mfraction<T>(-a.num,a.den);
}

template<class T>
mfraction<T> operator+(const mfraction<T> & a,const mfraction<T> & b)
{
   return mfraction<T>(a.num*b.den+a.den*b.num,a.den*b.den);   
}

template<class T>
mfraction<T> operator-(const mfraction<T> & a,const mfraction<T> & b)
{
   return mfraction<T>(a.num*b.den-a.den*b.num,a.den*b.den);   
}

template<class T>
mfraction<T> operator*(const mfraction<T> & a,const mfraction<T> & b)
{
   return mfraction<T>(a.num*b.num,a.den*b.den);   
}

template<class T>
mfraction<T> operator/(const mfraction<T> & a,const mfraction<T> & b)
{
   return mfraction<T>(a.num*b.den,a.den*b.num);   
}


#endif


syntax highlighted by Code2HTML, v. 0.9.1