- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

# 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 NUMType, typename DENType>
    00032     inline
    00033     TRationalNumber<NUMType, DENType>::TRationalNumber ()
    00034     : num_ (NUMType(0)), // 0 or 1
    00035       den_ (DENType(1))
    00036     {
    00037     }
    00038
    00039     template<typename NUMType, typename DENType>
    00040     inline
    00041     TRationalNumber<NUMType, DENType>::TRationalNumber (const NUMType num)
    00042     : num_ (num),
    00043       den_ (DENType(1))
    00044     {
    00045     }
    00046
    00047     template<typename NUMType, typename DENType>
    00048     inline
    00049     TRationalNumber<NUMType, DENType>::TRationalNumber (const NUMType num, const DENType den)
    00050     {
    00051       set_rational (num, den);
    00052     }
    00053
    00054     template<typename NUMType, typename DENType>
    00055     inline
    00056     TRationalNumber<NUMType, DENType>::TRationalNumber (const TRationalNumber<NUMType, DENType>& nb)
    00057     {
    00058       set_rational (nb.num_, nb.den_);
    00059     }
    00060
    00061     template<typename NUMType, typename DENType>
    00062     inline
    00063     TRationalNumber<NUMType, DENType>::~TRationalNumber ()
    00064     {}
    00065
    00066     template<typename NUMType, typename DENType>
    00067     inline
    00068     vcsn::algebra::TRationalNumber<NUMType, DENType>&
    00069     TRationalNumber<NUMType, DENType>::set (const NUMType num, const DENType den)
    00070     {
    00071       set_rational (num, den);
    00072       return (*this);
    00073     }
    00074
    00075     template<typename NUMType, typename DENType>
    00076     inline
    00077     NUMType
    00078     TRationalNumber<NUMType, DENType>::num_get () const
    00079     {
    00080       return num_;
    00081     }
    00082
    00083     template<typename NUMType, typename DENType>
    00084     inline
    00085     DENType
    00086     TRationalNumber<NUMType, DENType>::den_get () const
    00087     {
    00088       return den_;
    00089     }
    00090
    00091     template<typename NUMType, typename DENType>
    00092     inline
    00093     std::ostream&
    00094     TRationalNumber<NUMType, DENType>::print (std::ostream& ostr) const
    00095     {
    00096       if (den_ != 1)
    00097         return ostr << num_ << '/' << den_;
    00098       return ostr << num_;
    00099     }
    00100
    00101     template<typename NUMType, typename DENType>
    00102     inline
    00103     TRationalNumber<NUMType, DENType>
    00104     TRationalNumber<NUMType, DENType>::operator+ (const TRationalNumber<NUMType, DENType>& nb) const
    00105     {
    00106       return TRationalNumber<NUMType, DENType> (num_ * nb.den_ + nb.num_ * den_, den_ * nb.den_);
    00107     }
    00108
    00109     template<typename NUMType, typename DENType>
    00110     inline
    00111     TRationalNumber<NUMType, DENType>
    00112     TRationalNumber<NUMType, DENType>::operator- (const TRationalNumber<NUMType, DENType>& nb) const
    00113     {
    00114       using vcsn::misc::abs;
    00115       NUMType a = den_;
    00116       NUMType b = nb.den_;
    00117
    00118       return TRationalNumber<NUMType, DENType> ((num_ * b) - (nb.num_ * a), den_ * nb.den_);
    00119     }
    00120
    00121     template<typename NUMType, typename DENType>
    00122     inline
    00123     TRationalNumber<NUMType, DENType>
    00124     TRationalNumber<NUMType, DENType>::operator- () const
    00125     {
    00126       return TRationalNumber<NUMType, DENType> (- num_, den_);
    00127     }
    00128
    00129     template<typename NUMType, typename DENType>
    00130     inline
    00131     TRationalNumber<NUMType, DENType>
    00132     TRationalNumber<NUMType, DENType>::operator* (const TRationalNumber<NUMType, DENType>& nb) const
    00133     {
    00134       NUMType d1 = vcsn::misc::gcd (vcsn::misc::abs(num_), nb.den_get ());
    00135       NUMType d2 = vcsn::misc::gcd (den_, vcsn::misc::abs(nb.num_get ()));
    00136
    00137       return TRationalNumber<NUMType, DENType> ((num_ / d1) * (nb.num_get () / d2),
    00138                              (den_ / d2) * (nb.den_get () / d1));
    00139     }
    00140
    00141     template<typename NUMType, typename DENType>
    00142     inline
    00143     TRationalNumber<NUMType, DENType>
    00144     TRationalNumber<NUMType, DENType>::operator/ (const TRationalNumber<NUMType, DENType>& nb) const
    00145     {
    00146       NUMType signe = 1;
    00147       assert(nb.num_ != 0);
    00148       NUMType numgcd = vcsn::misc::gcd (vcsn::misc::abs (num_), vcsn::misc::abs (nb.num_));
    00149       NUMType dengcd = vcsn::misc::gcd (den_, nb.den_);
    00150       if(nb.num_ < 0)
    00151         signe = -1;
    00152       return TRationalNumber<NUMType, DENType> (signe * ((num_ / numgcd)
    00153                                                          * ((NUMType) nb.den_get() /dengcd)),
    00154                                                 (signe * nb.num_get()
    00155                                                          / numgcd) *
    00156                                                 (den_ / dengcd));
    00157     }
    00158
    00159     template<typename NUMType, typename DENType>
    00160     inline
    00161     TRationalNumber<NUMType, DENType>&
    00162     TRationalNumber<NUMType, DENType>::operator+= (const TRationalNumber<NUMType, DENType>& nb)
    00163     {
    00164       // std::cout << "+=" << std::endl;
    00165       // std::cout << *this << '+' << nb << "= " << num_ * nb.den_ +
    00166       //        nb.num_ * den_ << '\'' << den_ * nb.den_<< std::endl;
    00167       set_rational (num_ * nb.den_ + nb.num_ * den_, den_ * nb.den_);
    00168       return (*this);
    00169     }
    00170
    00171     template<typename NUMType, typename DENType>
    00172     inline
    00173     TRationalNumber<NUMType, DENType>&
    00174     TRationalNumber<NUMType, DENType>::operator-= (const TRationalNumber<NUMType, DENType>& nb)
    00175     {
    00176       set_rational (num_ * nb.den_ - nb.num_ * den_, den_ * nb.den_);
    00177       return (*this);
    00178     }
    00179
    00180     template<typename NUMType, typename DENType>
    00181     inline
    00182     TRationalNumber<NUMType, DENType>&
    00183     TRationalNumber<NUMType, DENType>::operator*= (const TRationalNumber<NUMType, DENType>& nb)
    00184     {
    00185       DENType d1 = vcsn::misc::gcd (vcsn::misc::abs(num_), nb.den_get ());
    00186       DENType d2 = vcsn::misc::gcd (den_, vcsn::misc::abs(nb.num_get ()));
    00187       set_unsafe_rational ((num_ / d1) * (nb.num_get () / d2),
    00188                            (den_ / d2) * (nb.den_get () / d1));
    00189       return (*this);
    00190     }
    00191
    00192     template<typename NUMType, typename DENType>
    00193     inline
    00194     TRationalNumber<NUMType, DENType>&
    00195     TRationalNumber<NUMType, DENType>::operator/= (const TRationalNumber<NUMType, DENType>& nb)
    00196     {
    00197       NUMType signe = 1;
    00198       assert(nb.num_ != 0);
    00199       NUMType numgcd = vcsn::misc::gcd (vcsn::misc::abs (num_), vcsn::misc::abs (nb.num_));
    00200       NUMType dengcd = vcsn::misc::gcd (den_, nb.den_);
    00201       if(nb.num_ < 0)
    00202         signe = -1;
    00203       set_unsafe_rational (signe * ((num_ / numgcd) * ((NUMType) nb.den_get() /dengcd)),
    00204                                                 (signe * nb.num_get() / numgcd) * (den_ / dengcd));
    00205       return *this;
    00206     }
    00207
    00208     template<typename NUMType, typename DENType>
    00209     inline
    00210     bool
    00211     TRationalNumber<NUMType, DENType>::operator== (const TRationalNumber<NUMType, DENType>& nb) const
    00212     {
    00213       //return (den_ * nb.num_ == nb.den_ * num_);
    00214        if (!num_)
    00215          return (!nb.num_);
    00216        return (den_ == nb.den_) && (num_ == nb.num_);
    00217     }
    00218
    00219     template<typename NUMType, typename DENType>
    00220     inline
    00221     bool
    00222     TRationalNumber<NUMType, DENType>::operator!= (const TRationalNumber<NUMType, DENType>& nb) const
    00223     {
    00224       // return (den_ * nb.num_ != nb.den_ * num_);
    00225       if (!num_)
    00226         return (!!nb.num_);
    00227       return (den_ != nb.den_) || (num_ != nb.num_);
    00228     }
    00229
    00230     template<typename NUMType, typename DENType>
    00231     inline
    00232     bool
    00233     TRationalNumber<NUMType, DENType>::operator< (const TRationalNumber<NUMType, DENType>& nb) const
    00234     {
    00235       return num_ * nb.den_ < nb.num_ * den_;
    00236     }
    00237
    00238     template<typename NUMType, typename DENType>
    00239     inline
    00240     bool
    00241     TRationalNumber<NUMType, DENType>::operator<= (const TRationalNumber<NUMType, DENType>& nb) const
    00242     {
    00243       return num_ * nb.den_ <= nb.num_ * den_;
    00244     }
    00245
    00246     template<typename NUMType, typename DENType>
    00247     inline
    00248     bool
    00249     TRationalNumber<NUMType, DENType>::operator> (const TRationalNumber<NUMType, DENType>& nb) const
    00250     {
    00251       return num_ * nb.den_ > nb.num_ * den_;
    00252     }
    00253
    00254     template<typename NUMType, typename DENType>
    00255     inline
    00256     bool
    00257     TRationalNumber<NUMType, DENType>::operator>= (const TRationalNumber<NUMType, DENType>& nb) const
    00258     {
    00259       return num_ * nb.den_ >= nb.num_ * den_;
    00260     }
    00261
    00262     template<typename NUMType, typename DENType>
    00263     inline
    00264     TRationalNumber<NUMType, DENType>::operator float () const
    00265     {
    00266       return to_float ();
    00267     }
    00268
    00269     template<typename NUMType, typename DENType>
    00270     inline
    00271     int
    00272     TRationalNumber<NUMType, DENType>::to_int () const
    00273     {
    00274       return num_ / den_;
    00275     }
    00276
    00277     template<typename NUMType, typename DENType>
    00278     inline
    00279     float
    00280     TRationalNumber<NUMType, DENType>::to_float () const
    00281     {
    00282       return (static_cast<float> (num_)) / den_;
    00283     }
    00284
    00285     template<typename NUMType, typename DENType>
    00286     inline
    00287     double
    00288     TRationalNumber<NUMType, DENType>::to_double () const
    00289     {
    00290       return (static_cast<double> (num_)) / den_;
    00291     }
    00292 #include <iostream>
    00293     template<typename NUMType, typename DENType>
    00294     inline
    00295     void
    00296     TRationalNumber<NUMType, DENType>::set_rational (const NUMType num, const DENType den)
    00297     {
    00298       if (num)
    00299       {
    00300         assert(den);
    00301         NUMType div = vcsn::misc::gcd(vcsn::misc::abs(num), den);
    00302         if (div < 0)
    00303           std::cout << "false";
    00304         num_ = num / div;
    00305         den_ = den / div;
    00306         if (1  != vcsn::misc::gcd(vcsn::misc::abs(num_), den_)) {
    00307           std::cout << num_ << ' ' << den_ << std::endl;
    00308         }
    00309
    00310
    00311         assert(1u == vcsn::misc::gcd(vcsn::misc::abs(num_), den_));
    00312         return;
    00313       }
    00314       else
    00315       {
    00316         num_ = 0;
    00317         den_ = 1;
    00318         return;
    00319       }
    00320     }
    00321
    00322     template<typename NUMType, typename DENType>
    00323     inline
    00324     void
    00325     TRationalNumber<NUMType, DENType>::set_unsafe_rational (const NUMType num, const DENType den)
    00326     {
    00327       assert (den != 0);
    00328
    00329       num_ = num;
    00330       den_ = den;
    00331
    00332       assert (vcsn::misc::is_coprime (num_, den_));
    00333     }
    00334
    00335     template<typename NUMType, typename DENType>
    00336     inline
    00337     void
    00338     TRationalNumber<NUMType, DENType>::set_rational ()
    00339     {
    00340       set_rational (num_, den_);
    00341     }
    00342
    00343     template<typename NUMType, typename DENType>
    00344     inline
    00345     std::ostream&
    00346     operator<< (std::ostream& ostr, const TRationalNumber<NUMType, DENType>& nb)
    00347     {
    00348       nb.print (ostr);
    00349       return ostr;
    00350     }
    00351
    00352     template<typename NUMType, typename DENType>
    00353     inline
    00354     std::istream&
    00355     operator>> (std::istream& istr, TRationalNumber<NUMType, DENType>& a)
    00356     {
    00357       NUMType num;
    00358
    00359       istr >> num;
    00360       char slash;
    00361       if (!istr.eof())
    00362         istr.get(slash);
    00363       if ('/' != slash) // Test if a slash is present.
    00364       {
    00365         istr.unget();
    00366         a.set(num, 1);
    00367         return istr;
    00368        }
    00369
    00370       // Otherwise read the denominator.
    00371       DENType den;
    00372       istr >> den;
    00373       a.set(num, den);
    00374
    00375       return istr;
    00376     }
    00377   } // !algebra
    00378
    00379 } // !vcsn
    00380
    00381 #endif // ! VCSN_ALGEBRA_IMPLEMENTATION_SEMIRING_Q_NUMBER_HXX