Vaucanson  1.4.1
q_number.hxx
1 // q_number.hxx: this file is part of the Vaucanson project.
2 //
3 // Vaucanson, a generic library for finite state machines.
4 //
5 // Copyright (C) 2011 The Vaucanson Group.
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
11 //
12 // The complete GNU General Public Licence Notice can be found as the
13 // `COPYING' file in the root directory.
14 //
15 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
16 //
17 #ifndef VCSN_ALGEBRA_IMPLEMENTATION_SEMIRING_Q_NUMBER_HXX
18 # define VCSN_ALGEBRA_IMPLEMENTATION_SEMIRING_Q_NUMBER_HXX
19 
21 # include <vaucanson/misc/algebra.hh>
23 
24 # include <iostream>
25 # include <cassert>
26 
27 namespace vcsn {
28 
29  namespace algebra {
30 
31  template<typename IntType>
32  inline
34  : num_ (IntType(0)), // 0 or 1
35  den_ (IntType(1))
36  {
37  }
38 
39  template<typename IntType>
40  inline
42  : num_ (num),
43  den_ (IntType(1))
44  {
45  }
46 
47  template<typename IntType>
48  inline
49  TRationalNumber<IntType>::TRationalNumber (const IntType num, const IntType den)
50  {
51  set_rational (num, den);
52  }
53 
54  template<typename IntType>
55  inline
57  {
58  set_rational (nb.num_, nb.den_);
59  }
60 
61  template<typename IntType>
62  inline
64  {}
65 
66  template<typename IntType>
67  inline
69  TRationalNumber<IntType>::set (const IntType num, const IntType den)
70  {
71  set_rational (num, den);
72  return (*this);
73  }
74 
75  template<typename IntType>
76  inline
77  IntType
79  {
80  return num_;
81  }
82 
83  template<typename IntType>
84  inline
85  IntType
87  {
88  return den_;
89  }
90 
91  template<typename IntType>
92  inline
93  std::ostream&
94  TRationalNumber<IntType>::print (std::ostream& ostr) const
95  {
96  if (den_ != 1)
97  return ostr << num_ << '/' << den_;
98  return ostr << num_;
99  }
100 
101  template<typename IntType>
102  inline
105  {
106  TRationalNumber<IntType> r(*this);
107  r+=nb;
108  return r;
109  }
110 
111  template<typename IntType>
112  inline
115  {
116  TRationalNumber<IntType> r(*this);
117  r-=nb;
118  return r;
119  }
120 
121  template<typename IntType>
122  inline
125  {
126  return TRationalNumber<IntType> (- num_, den_);
127  }
128 
129  template<typename IntType>
130  inline
133  {
134  TRationalNumber<IntType> r(*this);
135  r*=nb;
136  return r;
137  }
138 
139  template<typename IntType>
140  inline
143  {
144  TRationalNumber<IntType> r(*this);
145  r/=nb;
146  return r;
147 
148  }
149 
150  template<typename IntType>
151  inline
154  {
155  IntType g = vcsn::misc::gcd(den_,nb.den_);
156  set_rational (nb.den_ / g * num_+ den_ / g * nb.num_, den_ / g * nb.den_);
157  return (*this);
158  }
159 
160  template<typename IntType>
161  inline
164  {
165  IntType g = vcsn::misc::gcd(den_,nb.den_);
166  set_rational (nb.den_ / g * num_ - den_ / g * nb.num_, den_ / g * nb.den_);
167  return (*this);
168  }
169 
170  template<typename IntType>
171  inline
174  {
175  IntType d1 = vcsn::misc::gcd (num_, nb.den_);
176  IntType d2 = vcsn::misc::gcd (den_, nb.num_);
177  set_unsafe_rational ((num_ / d1) * (nb.num_ / d2),
178  (den_ / d2) * (nb.den_ / d1));
179  return (*this);
180  }
181 
182  template<typename IntType>
183  inline
186  {
187  assert(nb.num_ != 0);
188  IntType d1 = vcsn::misc::gcd (num_, nb.num_);// negative iff nb.num_ negative
189  IntType d2 = vcsn::misc::gcd (den_, nb.den_);
190  set_unsafe_rational ((num_ / d1) * (nb.den_ / d2),
191  (nb.num_ / d1) * (den_ / d2));
192  return *this;
193  }
194 
195  template<typename IntType>
196  inline
197  bool
199  {
200  if (!num_)
201  return (!nb.num_);
202  return (den_ == nb.den_) && (num_ == nb.num_);
203  }
204 
205  template<typename IntType>
206  inline
207  bool
209  {
210  return !(*this == nb);
211  }
212 
213  template<typename IntType>
214  inline
215  bool
217  {
218  return (num_ * nb.den_ < nb.num_ * den_);
219  }
220 
221  template<typename IntType>
222  inline
223  bool
225  {
226  return !(nb<*this);
227  }
228 
229  template<typename IntType>
230  inline
231  bool
233  {
234  return nb<*this;;
235  }
236 
237  template<typename IntType>
238  inline
239  bool
241  {
242  return !(*this<nb);
243  }
244 
245  template<typename IntType>
246  inline
248  {
249  return to_double ();
250  }
251 
252  template<typename IntType>
253  inline
254  IntType
256  {
257  return num_ / den_;
258  }
259 
260  template<typename IntType>
261  inline
262  float
264  {
265  return (static_cast<float> (num_)) / den_;
266  }
267 
268  template<typename IntType>
269  inline
270  double
272  {
273  return (static_cast<double> (num_)) / den_;
274  }
275 #include <iostream>
276  template<typename IntType>
277  inline
278  void
279  TRationalNumber<IntType>::set_rational (const IntType num, const IntType den)
280  {
281  assert(den);
282  IntType div = vcsn::misc::gcd(num, den); //negative iff den negative
283  num_ = num / div;
284  den_ = den / div;
285  }
286 
287  template<typename IntType>
288  inline
289  void
290  TRationalNumber<IntType>::set_unsafe_rational (const IntType num, const IntType den)
291  {
292  assert (den != 0);
293 
294  num_ = num;
295  den_ = den;
296 
297  assert (vcsn::misc::is_coprime (num_, den_));
298  }
299 
300  template<typename IntType>
301  inline
302  void
304  {
305  set_rational (num_, den_);
306  }
307 
308  template<typename IntType>
309  inline
310  std::ostream&
311  operator<< (std::ostream& ostr, const TRationalNumber<IntType>& nb)
312  {
313  nb.print (ostr);
314  return ostr;
315  }
316 
317  template<typename IntType>
318  inline
319  std::istream&
320  operator>> (std::istream& istr, TRationalNumber<IntType>& a)
321  {
322  IntType num;
323 
324  istr >> num;
325  char slash;
326  if (!istr.eof())
327  istr.get(slash);
328  if ('/' != slash) // Test if a slash is present.
329  {
330  istr.unget();
331  a.set(num, 1);
332  return istr;
333  }
334 
335  // Otherwise read the denominator.
336  IntType den;
337  istr >> den;
338  a.set(num, den);
339 
340  return istr;
341  }
342  } // !algebra
343 
344 } // !vcsn
345 
346 #endif // ! VCSN_ALGEBRA_IMPLEMENTATION_SEMIRING_Q_NUMBER_HXX