Vaucanson 1.4
q_number.hxx
00001 // q_number.hxx: this file is part of the Vaucanson project.
00002 //
00003 // Vaucanson, a generic library for finite state machines.
00004 //
00005 // Copyright (C) 2011 The Vaucanson Group.
00006 //
00007 // This program is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2
00010 // of the License, or (at your option) any later version.
00011 //
00012 // The complete GNU General Public Licence Notice can be found as the
00013 // `COPYING' file in the root directory.
00014 //
00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
00016 //
00017 #ifndef VCSN_ALGEBRA_IMPLEMENTATION_SEMIRING_Q_NUMBER_HXX
00018 # define VCSN_ALGEBRA_IMPLEMENTATION_SEMIRING_Q_NUMBER_HXX
00019 
00020 # include <vaucanson/algebra/implementation/semiring/q_number.hh>
00021 # include <vaucanson/misc/algebra.hh>
00022 # include <vaucanson/misc/contract.hh>
00023 
00024 # include <iostream>
00025 # include <cassert>
00026 
00027 namespace vcsn {
00028 
00029   namespace algebra {
00030 
00031     template<typename IntType>
00032     inline
00033     TRationalNumber<IntType>::TRationalNumber ()
00034     : num_ (IntType(0)), // 0 or 1
00035       den_ (IntType(1))
00036     {
00037     }
00038 
00039     template<typename IntType>
00040     inline
00041     TRationalNumber<IntType>::TRationalNumber (const IntType num)
00042     : num_ (num),
00043       den_ (IntType(1))
00044     {
00045     }
00046 
00047     template<typename IntType>
00048     inline
00049     TRationalNumber<IntType>::TRationalNumber (const IntType num, const IntType den)
00050     {
00051       set_rational (num, den);
00052     }
00053 
00054     template<typename IntType>
00055     inline
00056     TRationalNumber<IntType>::TRationalNumber (const TRationalNumber<IntType>& nb)
00057     {
00058       set_rational (nb.num_, nb.den_);
00059     }
00060 
00061     template<typename IntType>
00062     inline
00063     TRationalNumber<IntType>::~TRationalNumber ()
00064     {}
00065 
00066     template<typename IntType>
00067     inline
00068     vcsn::algebra::TRationalNumber<IntType>&
00069     TRationalNumber<IntType>::set (const IntType num, const IntType den)
00070     {
00071       set_rational (num, den);
00072       return (*this);
00073     }
00074 
00075     template<typename IntType>
00076     inline
00077     IntType
00078     TRationalNumber<IntType>::num_get () const
00079     {
00080       return num_;
00081     }
00082 
00083     template<typename IntType>
00084     inline
00085     IntType
00086     TRationalNumber<IntType>::den_get () const
00087     {
00088       return den_;
00089     }
00090 
00091     template<typename IntType>
00092     inline
00093     std::ostream&
00094     TRationalNumber<IntType>::print (std::ostream& ostr) const
00095     {
00096       if (den_ != 1)
00097         return ostr << num_ << '/' << den_;
00098       return ostr << num_;
00099     }
00100 
00101     template<typename IntType>
00102     inline
00103     TRationalNumber<IntType>
00104     TRationalNumber<IntType>::operator+ (const TRationalNumber<IntType>& nb) const
00105     {
00106       TRationalNumber<IntType> r(*this);
00107           r+=nb;
00108       return r;
00109     }
00110 
00111     template<typename IntType>
00112     inline
00113     TRationalNumber<IntType>
00114     TRationalNumber<IntType>::operator- (const TRationalNumber<IntType>& nb) const
00115     {
00116       TRationalNumber<IntType> r(*this);
00117           r-=nb;
00118       return r;
00119     }
00120 
00121     template<typename IntType>
00122     inline
00123     TRationalNumber<IntType>
00124     TRationalNumber<IntType>::operator- () const
00125     {
00126       return TRationalNumber<IntType> (- num_, den_);
00127     }
00128 
00129     template<typename IntType>
00130     inline
00131     TRationalNumber<IntType>
00132     TRationalNumber<IntType>::operator* (const TRationalNumber<IntType>& nb) const
00133     {
00134       TRationalNumber<IntType> r(*this);
00135           r*=nb;
00136       return r;
00137     }
00138 
00139     template<typename IntType>
00140     inline
00141     TRationalNumber<IntType>
00142     TRationalNumber<IntType>::operator/ (const TRationalNumber<IntType>& nb) const
00143     {
00144       TRationalNumber<IntType> r(*this);
00145           r/=nb;
00146       return r;
00147 
00148     }
00149 
00150     template<typename IntType>
00151     inline
00152     TRationalNumber<IntType>&
00153     TRationalNumber<IntType>::operator+= (const TRationalNumber<IntType>& nb)
00154     {
00155       IntType g = vcsn::misc::gcd(den_,nb.den_); 
00156       set_rational (nb.den_ / g * num_+ den_ / g * nb.num_, den_ / g * nb.den_);
00157       return (*this);
00158     }
00159 
00160     template<typename IntType>
00161     inline
00162     TRationalNumber<IntType>&
00163     TRationalNumber<IntType>::operator-= (const TRationalNumber<IntType>& nb)
00164     {
00165       IntType g = vcsn::misc::gcd(den_,nb.den_); 
00166       set_rational (nb.den_ / g * num_ - den_ / g * nb.num_, den_ / g * nb.den_);
00167       return (*this);
00168     }
00169 
00170     template<typename IntType>
00171     inline
00172     TRationalNumber<IntType>&
00173     TRationalNumber<IntType>::operator*= (const TRationalNumber<IntType>& nb)
00174     {
00175       IntType d1 = vcsn::misc::gcd (num_, nb.den_);
00176       IntType d2 = vcsn::misc::gcd (den_, nb.num_);
00177       set_unsafe_rational ((num_ / d1) * (nb.num_ / d2),
00178                            (den_ / d2) * (nb.den_ / d1));
00179       return (*this);
00180     }
00181 
00182     template<typename IntType>
00183     inline
00184     TRationalNumber<IntType>&
00185     TRationalNumber<IntType>::operator/= (const TRationalNumber<IntType>& nb)
00186     {
00187       assert(nb.num_ != 0);
00188       IntType d1 = vcsn::misc::gcd (num_, nb.num_);// negative iff nb.num_ negative
00189       IntType d2 = vcsn::misc::gcd (den_, nb.den_);
00190       set_unsafe_rational ((num_ / d1) * (nb.den_ / d2),
00191                                                 (nb.num_ / d1) * (den_ / d2));
00192       return *this;
00193     }
00194 
00195     template<typename IntType>
00196     inline
00197     bool
00198     TRationalNumber<IntType>::operator== (const TRationalNumber<IntType>& nb) const
00199     {
00200        if (!num_)
00201                  return (!nb.num_);
00202        return (den_ == nb.den_) && (num_ == nb.num_);
00203     }
00204 
00205     template<typename IntType>
00206     inline
00207     bool
00208     TRationalNumber<IntType>::operator!= (const TRationalNumber<IntType>& nb) const
00209     {
00210       return !(*this == nb);
00211     }
00212 
00213     template<typename IntType>
00214     inline
00215     bool
00216     TRationalNumber<IntType>::operator< (const TRationalNumber<IntType>& nb) const
00217     {
00218       return (num_ * nb.den_ < nb.num_ * den_);
00219     }
00220 
00221     template<typename IntType>
00222     inline
00223     bool
00224     TRationalNumber<IntType>::operator<= (const TRationalNumber<IntType>& nb) const
00225     {
00226       return !(nb<*this);
00227     }
00228 
00229     template<typename IntType>
00230     inline
00231     bool
00232     TRationalNumber<IntType>::operator> (const TRationalNumber<IntType>& nb) const
00233     {
00234       return nb<*this;;
00235     }
00236 
00237     template<typename IntType>
00238     inline
00239     bool
00240     TRationalNumber<IntType>::operator>= (const TRationalNumber<IntType>& nb) const
00241     {
00242       return !(*this<nb);
00243     }
00244 
00245     template<typename IntType>
00246     inline
00247     TRationalNumber<IntType>::operator double () const
00248     {
00249       return to_double ();
00250     }
00251 
00252     template<typename IntType>
00253     inline
00254     IntType
00255     TRationalNumber<IntType>::to_integer () const
00256     {
00257       return num_ / den_;
00258     }
00259 
00260     template<typename IntType>
00261     inline
00262     float
00263     TRationalNumber<IntType>::to_float () const
00264     {
00265       return (static_cast<float> (num_)) / den_;
00266     }
00267 
00268     template<typename IntType>
00269     inline
00270     double
00271     TRationalNumber<IntType>::to_double () const
00272     {
00273       return (static_cast<double> (num_)) / den_;
00274     }
00275 #include <iostream>
00276     template<typename IntType>
00277     inline
00278     void
00279     TRationalNumber<IntType>::set_rational (const IntType num, const IntType den)
00280     {
00281         assert(den);
00282         IntType div = vcsn::misc::gcd(num, den); //negative iff den negative
00283         num_ = num / div;
00284         den_ = den / div;
00285         }
00286 
00287     template<typename IntType>
00288     inline
00289     void
00290     TRationalNumber<IntType>::set_unsafe_rational (const IntType num, const IntType den)
00291     {
00292       assert (den != 0);
00293 
00294       num_ = num;
00295       den_ = den;
00296 
00297       assert (vcsn::misc::is_coprime (num_, den_));
00298     }
00299 
00300     template<typename IntType>
00301     inline
00302     void
00303     TRationalNumber<IntType>::set_rational ()
00304     {
00305       set_rational (num_, den_);
00306     }
00307 
00308     template<typename IntType>
00309     inline
00310     std::ostream&
00311     operator<< (std::ostream& ostr, const TRationalNumber<IntType>& nb)
00312     {
00313       nb.print (ostr);
00314       return ostr;
00315     }
00316 
00317     template<typename IntType>
00318     inline
00319     std::istream&
00320     operator>> (std::istream& istr, TRationalNumber<IntType>& a)
00321     {
00322       IntType num;
00323 
00324       istr >> num;
00325       char slash;
00326       if (!istr.eof())
00327         istr.get(slash);
00328       if ('/' != slash) // Test if a slash is present.
00329       {
00330         istr.unget();
00331         a.set(num, 1);
00332         return istr;
00333        }
00334 
00335       // Otherwise read the denominator.
00336       IntType den;
00337       istr >> den;
00338       a.set(num, den);
00339 
00340       return istr;
00341     }
00342   } // !algebra
00343 
00344 } // !vcsn
00345 
00346 #endif // ! VCSN_ALGEBRA_IMPLEMENTATION_SEMIRING_Q_NUMBER_HXX