libstdc++
ratio
Go to the documentation of this file.
1 // ratio -*- C++ -*-
2 
3 // Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /** @file include/ratio
26  * This is a Standard C++ Library header.
27  */
28 
29 #ifndef _GLIBCXX_RATIO
30 #define _GLIBCXX_RATIO 1
31 
32 #pragma GCC system_header
33 
34 #ifndef __GXX_EXPERIMENTAL_CXX0X__
35 # include <bits/c++0x_warning.h>
36 #else
37 
38 #include <type_traits>
39 #include <cstdint>
40 
41 #ifdef _GLIBCXX_USE_C99_STDINT_TR1
42 
43 namespace std _GLIBCXX_VISIBILITY(default)
44 {
45 _GLIBCXX_BEGIN_NAMESPACE_VERSION
46 
47  /**
48  * @defgroup ratio Rational Arithmetic
49  * @ingroup utilities
50  *
51  * Compile time representation of finite rational numbers.
52  * @{
53  */
54 
55  template<intmax_t _Pn>
56  struct __static_sign
57  : integral_constant<intmax_t, (_Pn < 0) ? -1 : 1>
58  { };
59 
60  template<intmax_t _Pn>
61  struct __static_abs
62  : integral_constant<intmax_t, _Pn * __static_sign<_Pn>::value>
63  { };
64 
65  template<intmax_t _Pn, intmax_t _Qn>
66  struct __static_gcd;
67 
68  template<intmax_t _Pn, intmax_t _Qn>
69  struct __static_gcd
70  : __static_gcd<_Qn, (_Pn % _Qn)>
71  { };
72 
73  template<intmax_t _Pn>
74  struct __static_gcd<_Pn, 0>
75  : integral_constant<intmax_t, __static_abs<_Pn>::value>
76  { };
77 
78  template<intmax_t _Qn>
79  struct __static_gcd<0, _Qn>
80  : integral_constant<intmax_t, __static_abs<_Qn>::value>
81  { };
82 
83  // Let c = 2^(half # of bits in an intmax_t)
84  // then we find a1, a0, b1, b0 s.t. N = a1*c + a0, M = b1*c + b0
85  // The multiplication of N and M becomes,
86  // N * M = (a1 * b1)c^2 + (a0 * b1 + b0 * a1)c + a0 * b0
87  // Multiplication is safe if each term and the sum of the terms
88  // is representable by intmax_t.
89  template<intmax_t _Pn, intmax_t _Qn>
90  struct __safe_multiply
91  {
92  private:
93  static const uintmax_t __c = uintmax_t(1) << (sizeof(intmax_t) * 4);
94 
95  static const uintmax_t __a0 = __static_abs<_Pn>::value % __c;
96  static const uintmax_t __a1 = __static_abs<_Pn>::value / __c;
97  static const uintmax_t __b0 = __static_abs<_Qn>::value % __c;
98  static const uintmax_t __b1 = __static_abs<_Qn>::value / __c;
99 
100  static_assert(__a1 == 0 || __b1 == 0,
101  "overflow in multiplication");
102  static_assert(__a0 * __b1 + __b0 * __a1 < (__c >> 1),
103  "overflow in multiplication");
104  static_assert(__b0 * __a0 <= __INTMAX_MAX__,
105  "overflow in multiplication");
106  static_assert((__a0 * __b1 + __b0 * __a1) * __c <=
107  __INTMAX_MAX__ - __b0 * __a0, "overflow in multiplication");
108 
109  public:
110  static const intmax_t value = _Pn * _Qn;
111  };
112 
113  // Helpers for __safe_add
114  template<intmax_t _Pn, intmax_t _Qn, bool>
115  struct __add_overflow_check_impl
116  : integral_constant<bool, (_Pn <= __INTMAX_MAX__ - _Qn)>
117  { };
118 
119  template<intmax_t _Pn, intmax_t _Qn>
120  struct __add_overflow_check_impl<_Pn, _Qn, false>
121  : integral_constant<bool, (_Pn >= -__INTMAX_MAX__ - _Qn)>
122  { };
123 
124  template<intmax_t _Pn, intmax_t _Qn>
125  struct __add_overflow_check
126  : __add_overflow_check_impl<_Pn, _Qn, (_Qn >= 0)>
127  { };
128 
129  template<intmax_t _Pn, intmax_t _Qn>
130  struct __safe_add
131  {
132  static_assert(__add_overflow_check<_Pn, _Qn>::value != 0,
133  "overflow in addition");
134 
135  static const intmax_t value = _Pn + _Qn;
136  };
137 
138  /**
139  * @brief Provides compile-time rational arithmetic.
140  *
141  * This class template represents any finite rational number with a
142  * numerator and denominator representable by compile-time constants of
143  * type intmax_t. The ratio is simplified when instantiated.
144  *
145  * For example:
146  * @code
147  * std::ratio<7,-21>::num == -1;
148  * std::ratio<7,-21>::den == 3;
149  * @endcode
150  *
151  */
152  template<intmax_t _Num, intmax_t _Den = 1>
153  struct ratio
154  {
155  static_assert(_Den != 0, "denominator cannot be zero");
156  static_assert(_Num >= -__INTMAX_MAX__ && _Den >= -__INTMAX_MAX__,
157  "out of range");
158 
159  // Note: sign(N) * abs(N) == N
160  static constexpr intmax_t num =
161  _Num * __static_sign<_Den>::value / __static_gcd<_Num, _Den>::value;
162 
163  static constexpr intmax_t den =
164  __static_abs<_Den>::value / __static_gcd<_Num, _Den>::value;
165 
166  typedef ratio<num, den> type;
167  };
168 
169  template<intmax_t _Num, intmax_t _Den>
170  constexpr intmax_t ratio<_Num, _Den>::num;
171 
172  template<intmax_t _Num, intmax_t _Den>
173  constexpr intmax_t ratio<_Num, _Den>::den;
174 
175  /// ratio_add
176  template<typename _R1, typename _R2>
177  struct ratio_add
178  {
179  private:
180  static constexpr intmax_t __gcd =
181  __static_gcd<_R1::den, _R2::den>::value;
182  static constexpr intmax_t __n = __safe_add<
183  __safe_multiply<_R1::num, (_R2::den / __gcd)>::value,
184  __safe_multiply<_R2::num, (_R1::den / __gcd)>::value>::value;
185 
186  // The new numerator may have common factors with the denominator,
187  // but they have to also be factors of __gcd.
188  static constexpr intmax_t __gcd2 = __static_gcd<__n, __gcd>::value;
189 
190  public:
191  typedef ratio<__n / __gcd2,
192  __safe_multiply<_R1::den / __gcd2, _R2::den / __gcd>::value> type;
193 
194  static constexpr intmax_t num = type::num;
195  static constexpr intmax_t den = type::den;
196  };
197 
198  template<typename _R1, typename _R2>
199  constexpr intmax_t ratio_add<_R1, _R2>::num;
200 
201  template<typename _R1, typename _R2>
202  constexpr intmax_t ratio_add<_R1, _R2>::den;
203 
204  /// ratio_subtract
205  template<typename _R1, typename _R2>
206  struct ratio_subtract
207  {
208  typedef typename ratio_add<
209  _R1,
210  ratio<-_R2::num, _R2::den>>::type type;
211 
212  static constexpr intmax_t num = type::num;
213  static constexpr intmax_t den = type::den;
214  };
215 
216  template<typename _R1, typename _R2>
217  constexpr intmax_t ratio_subtract<_R1, _R2>::num;
218 
219  template<typename _R1, typename _R2>
220  constexpr intmax_t ratio_subtract<_R1, _R2>::den;
221 
222  /// ratio_multiply
223  template<typename _R1, typename _R2>
224  struct ratio_multiply
225  {
226  private:
227  static const intmax_t __gcd1 =
228  __static_gcd<_R1::num, _R2::den>::value;
229  static const intmax_t __gcd2 =
230  __static_gcd<_R2::num, _R1::den>::value;
231 
232  public:
233  typedef ratio<
234  __safe_multiply<(_R1::num / __gcd1),
235  (_R2::num / __gcd2)>::value,
236  __safe_multiply<(_R1::den / __gcd2),
237  (_R2::den / __gcd1)>::value> type;
238 
239  static constexpr intmax_t num = type::num;
240  static constexpr intmax_t den = type::den;
241  };
242 
243  template<typename _R1, typename _R2>
244  constexpr intmax_t ratio_multiply<_R1, _R2>::num;
245 
246  template<typename _R1, typename _R2>
247  constexpr intmax_t ratio_multiply<_R1, _R2>::den;
248 
249  /// ratio_divide
250  template<typename _R1, typename _R2>
251  struct ratio_divide
252  {
253  static_assert(_R2::num != 0, "division by 0");
254 
255  typedef typename ratio_multiply<
256  _R1,
257  ratio<_R2::den, _R2::num>>::type type;
258 
259  static constexpr intmax_t num = type::num;
260  static constexpr intmax_t den = type::den;
261  };
262 
263  template<typename _R1, typename _R2>
264  constexpr intmax_t ratio_divide<_R1, _R2>::num;
265 
266  template<typename _R1, typename _R2>
267  constexpr intmax_t ratio_divide<_R1, _R2>::den;
268 
269  /// ratio_equal
270  template<typename _R1, typename _R2>
271  struct ratio_equal
272  : integral_constant<bool, _R1::num == _R2::num && _R1::den == _R2::den>
273  { };
274 
275  /// ratio_not_equal
276  template<typename _R1, typename _R2>
277  struct ratio_not_equal
278  : integral_constant<bool, !ratio_equal<_R1, _R2>::value>
279  { };
280 
281  // 0 <= _Ri < 1
282  // If one is 0, conclude
283  // Otherwise, x < y iff 1/y < 1/x
284  template<typename _R1, typename _R2>
285  struct __ratio_less_impl_2;
286 
287  // _Ri > 0
288  // Compare the integral parts, and remove them if they are equal
289  template<typename _R1, typename _R2, intmax_t __q1 = _R1::num / _R1::den,
290  intmax_t __q2 = _R2::num / _R2::den, bool __eq = (__q1 == __q2)>
291  struct __ratio_less_impl_1
292  : __ratio_less_impl_2<ratio<_R1::num % _R1::den, _R1::den>,
293  ratio<_R2::num % _R2::den, _R2::den> >::type
294  { };
295 
296  template<typename _R1, typename _R2, intmax_t __q1, intmax_t __q2>
297  struct __ratio_less_impl_1<_R1, _R2, __q1, __q2, false>
298  : integral_constant<bool, (__q1 < __q2) >
299  { };
300 
301  template<typename _R1, typename _R2>
302  struct __ratio_less_impl_2
303  : __ratio_less_impl_1<ratio<_R2::den, _R2::num>,
304  ratio<_R1::den, _R1::num> >::type
305  { };
306 
307  template<intmax_t __d1, typename _R2>
308  struct __ratio_less_impl_2<ratio<0, __d1>, _R2>
309  : integral_constant<bool, true>
310  { };
311 
312  template<typename _R1, intmax_t __d2>
313  struct __ratio_less_impl_2<_R1, ratio<0, __d2> >
314  : integral_constant<bool, false>
315  { };
316 
317  template<intmax_t __d1, intmax_t __d2>
318  struct __ratio_less_impl_2<ratio<0, __d1>, ratio<0, __d2> >
319  : integral_constant<bool, false>
320  { };
321 
322  template<typename _R1, typename _R2,
323  bool = (_R1::num == 0 || _R2::num == 0
324  || (__static_sign<_R1::num>::value
325  != __static_sign<_R2::num>::value)),
326  bool = (__static_sign<_R1::num>::value == -1
327  && __static_sign<_R2::num>::value == -1)>
328  struct __ratio_less_impl
329  : __ratio_less_impl_1<_R1, _R2>::type
330  { };
331 
332  template<typename _R1, typename _R2>
333  struct __ratio_less_impl<_R1, _R2, true, false>
334  : integral_constant<bool, _R1::num < _R2::num>
335  { };
336 
337  template<typename _R1, typename _R2>
338  struct __ratio_less_impl<_R1, _R2, false, true>
339  : __ratio_less_impl_1<ratio<-_R2::num, _R2::den>,
340  ratio<-_R1::num, _R1::den> >::type
341  { };
342 
343  /// ratio_less
344  // using a continued fraction expansion
345  template<typename _R1, typename _R2>
346  struct ratio_less
347  : __ratio_less_impl<_R1, _R2>::type
348  { };
349 
350  /// ratio_less_equal
351  template<typename _R1, typename _R2>
352  struct ratio_less_equal
353  : integral_constant<bool, !ratio_less<_R2, _R1>::value>
354  { };
355 
356  /// ratio_greater
357  template<typename _R1, typename _R2>
358  struct ratio_greater
359  : integral_constant<bool, ratio_less<_R2, _R1>::value>
360  { };
361 
362  /// ratio_greater_equal
363  template<typename _R1, typename _R2>
364  struct ratio_greater_equal
365  : integral_constant<bool, !ratio_less<_R1, _R2>::value>
366  { };
367 
368  typedef ratio<1, 1000000000000000000> atto;
369  typedef ratio<1, 1000000000000000> femto;
370  typedef ratio<1, 1000000000000> pico;
371  typedef ratio<1, 1000000000> nano;
372  typedef ratio<1, 1000000> micro;
373  typedef ratio<1, 1000> milli;
374  typedef ratio<1, 100> centi;
375  typedef ratio<1, 10> deci;
376  typedef ratio< 10, 1> deca;
377  typedef ratio< 100, 1> hecto;
378  typedef ratio< 1000, 1> kilo;
379  typedef ratio< 1000000, 1> mega;
380  typedef ratio< 1000000000, 1> giga;
381  typedef ratio< 1000000000000, 1> tera;
382  typedef ratio< 1000000000000000, 1> peta;
383  typedef ratio< 1000000000000000000, 1> exa;
384 
385  // @} group ratio
386 _GLIBCXX_END_NAMESPACE_VERSION
387 } // namespace
388 
389 #endif //_GLIBCXX_USE_C99_STDINT_TR1
390 
391 #endif //__GXX_EXPERIMENTAL_CXX0X__
392 
393 #endif //_GLIBCXX_RATIO