00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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)),
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_);
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);
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)
00329 {
00330 istr.unget();
00331 a.set(num, 1);
00332 return istr;
00333 }
00334
00335
00336 IntType den;
00337 istr >> den;
00338 a.set(num, den);
00339
00340 return istr;
00341 }
00342 }
00343
00344 }
00345
00346 #endif // ! VCSN_ALGEBRA_IMPLEMENTATION_SEMIRING_Q_NUMBER_HXX