Vaucanson 1.4
|
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