OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-src/] [gcc-4.5.1/] [gcc-4.5.1-or32-1.0rc4/] [libstdc++-v3/] [include/] [std/] [ratio] - Blame information for rev 519

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 424 jeremybenn
// ratio -*- C++ -*-
2
 
3
// Copyright (C) 2008, 2009, 2010 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
// .
24
 
25
/** @file 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 
36
#else
37
 
38
#include 
39
#include 
40
 
41
#ifdef _GLIBCXX_USE_C99_STDINT_TR1
42
 
43
namespace std
44
{
45
  /**
46
   * @defgroup ratio Rational Arithmetic
47
   * @ingroup utilities
48
   *
49
   * Compile time representation of finite rational numbers.
50
   * @{
51
   */
52
 
53
  template
54
    struct __static_sign
55
    : integral_constant
56
    { };
57
 
58
  template
59
    struct __static_abs
60
    : integral_constant::value>
61
    { };
62
 
63
  template
64
    struct __static_gcd;
65
 
66
  template
67
    struct __static_gcd
68
    : __static_gcd<_Qn, (_Pn % _Qn)>
69
    { };
70
 
71
  template
72
    struct __static_gcd<_Pn, 0>
73
    : integral_constant::value>
74
    { };
75
 
76
  template
77
    struct __static_gcd<0, _Qn>
78
    : integral_constant::value>
79
    { };
80
 
81
  // Let c = 2^(half # of bits in an intmax_t)
82
  // then we find a1, a0, b1, b0 s.t. N = a1*c + a0, M = b1*c + b0
83
  // The multiplication of N and M becomes,
84
  // N * M = (a1 * b1)c^2 + (a0 * b1 + b0 * a1)c + a0 * b0
85
  // Multiplication is safe if each term and the sum of the terms
86
  // is representable by intmax_t.
87
  template
88
    struct __safe_multiply
89
    {
90
    private:
91
      static const uintmax_t __c = uintmax_t(1) << (sizeof(intmax_t) * 4);
92
 
93
      static const uintmax_t __a0 = __static_abs<_Pn>::value % __c;
94
      static const uintmax_t __a1 = __static_abs<_Pn>::value / __c;
95
      static const uintmax_t __b0 = __static_abs<_Qn>::value % __c;
96
      static const uintmax_t __b1 = __static_abs<_Qn>::value / __c;
97
 
98
      static_assert(__a1 == 0 || __b1 == 0,
99
        "overflow in multiplication");
100
      static_assert(__a0 * __b1 + __b0 * __a1 < (__c >> 1),
101
        "overflow in multiplication");
102
      static_assert(__b0 * __a0 <= __INTMAX_MAX__,
103
        "overflow in multiplication");
104
      static_assert((__a0 * __b1 + __b0 * __a1) * __c <=
105
        __INTMAX_MAX__ -  __b0 * __a0, "overflow in multiplication");
106
 
107
    public:
108
      static const intmax_t value = _Pn * _Qn;
109
    };
110
 
111
  // Helpers for __safe_add
112
  template
113
    struct __add_overflow_check_impl
114
    : integral_constant
115
    { };
116
 
117
  template
118
    struct __add_overflow_check_impl<_Pn, _Qn, false>
119
    : integral_constant= -__INTMAX_MAX__ - _Qn)>
120
    { };
121
 
122
  template
123
    struct __add_overflow_check
124
    : __add_overflow_check_impl<_Pn, _Qn, (_Qn >= 0)>
125
    { };
126
 
127
  template
128
    struct __safe_add
129
    {
130
      static_assert(__add_overflow_check<_Pn, _Qn>::value != 0,
131
        "overflow in addition");
132
 
133
      static const intmax_t value = _Pn + _Qn;
134
    };
135
 
136
  /**
137
   *  @brief Provides compile-time rational arithmetic.
138
   *
139
   *  This class template represents any finite rational number with a
140
   *  numerator and denominator representable by compile-time constants of
141
   *  type intmax_t. The ratio is simplified when instantiated.
142
   *
143
   *  For example:
144
   *  @code
145
   *    std::ratio<7,-21>::num == -1;
146
   *    std::ratio<7,-21>::den == 3;
147
   *  @endcode
148
   *
149
  */
150
  template
151
    struct ratio
152
    {
153
      static_assert(_Den != 0, "denominator cannot be zero");
154
      static_assert(_Num >= -__INTMAX_MAX__ && _Den >= -__INTMAX_MAX__,
155
                    "out of range");
156
 
157
      // Note: sign(N) * abs(N) == N
158
      static const intmax_t num =
159
        _Num * __static_sign<_Den>::value / __static_gcd<_Num, _Den>::value;
160
 
161
      static const intmax_t den =
162
        __static_abs<_Den>::value / __static_gcd<_Num, _Den>::value;
163
    };
164
 
165
  template
166
    const intmax_t ratio<_Num, _Den>::num;
167
 
168
  template
169
    const intmax_t ratio<_Num, _Den>::den;
170
 
171
  /// ratio_add
172
  template
173
    struct ratio_add
174
    {
175
    private:
176
      static const intmax_t __gcd =
177
        __static_gcd<_R1::den, _R2::den>::value;
178
 
179
    public:
180
      typedef ratio<
181
        __safe_add<
182
          __safe_multiply<_R1::num, (_R2::den / __gcd)>::value,
183
          __safe_multiply<_R2::num, (_R1::den / __gcd)>::value>::value,
184
        __safe_multiply<_R1::den, (_R2::den / __gcd)>::value> type;
185
    };
186
 
187
  /// ratio_subtract
188
  template
189
    struct ratio_subtract
190
    {
191
      typedef typename ratio_add<
192
        _R1,
193
        ratio<-_R2::num, _R2::den>>::type type;
194
    };
195
 
196
  /// ratio_multiply
197
  template
198
    struct ratio_multiply
199
    {
200
    private:
201
      static const intmax_t __gcd1 =
202
        __static_gcd<_R1::num, _R2::den>::value;
203
      static const intmax_t __gcd2 =
204
        __static_gcd<_R2::num, _R1::den>::value;
205
 
206
    public:
207
      typedef ratio<
208
        __safe_multiply<(_R1::num / __gcd1),
209
                        (_R2::num / __gcd2)>::value,
210
        __safe_multiply<(_R1::den / __gcd2),
211
                        (_R2::den / __gcd1)>::value> type;
212
    };
213
 
214
  /// ratio_divide
215
  template
216
    struct ratio_divide
217
    {
218
      static_assert(_R2::num != 0, "division by 0");
219
 
220
      typedef typename ratio_multiply<
221
        _R1,
222
        ratio<_R2::den, _R2::num>>::type type;
223
    };
224
 
225
  /// ratio_equal
226
  template
227
    struct ratio_equal
228
    : integral_constant
229
    { };
230
 
231
  /// ratio_not_equal
232
  template
233
    struct ratio_not_equal
234
    : integral_constant::value>
235
    { };
236
 
237
  template
238
    struct __ratio_less_simple_impl
239
    : integral_constant
240
                        (__safe_multiply<_R1::num, _R2::den>::value
241
                         < __safe_multiply<_R2::num, _R1::den>::value)>
242
    { };
243
 
244
  // If the denominators are equal or the signs differ, we can just compare
245
  // numerators, otherwise fallback to the simple cross-multiply method.
246
  template
247
    struct __ratio_less_impl
248
    : conditional<(_R1::den == _R2::den
249
                   || (__static_sign<_R1::num>::value
250
                       != __static_sign<_R2::num>::value)),
251
      integral_constant,
252
      __ratio_less_simple_impl<_R1, _R2>>::type
253
    { };
254
 
255
  /// ratio_less
256
  template
257
    struct ratio_less
258
    : __ratio_less_impl<_R1, _R2>::type
259
    { };
260
 
261
  /// ratio_less_equal
262
  template
263
    struct ratio_less_equal
264
    : integral_constant::value>
265
    { };
266
 
267
  /// ratio_greater
268
  template
269
    struct ratio_greater
270
    : integral_constant::value>
271
    { };
272
 
273
  /// ratio_greater_equal
274
  template
275
    struct ratio_greater_equal
276
    : integral_constant::value>
277
    { };
278
 
279
  typedef ratio<1,       1000000000000000000> atto;
280
  typedef ratio<1,          1000000000000000> femto;
281
  typedef ratio<1,             1000000000000> pico;
282
  typedef ratio<1,                1000000000> nano;
283
  typedef ratio<1,                   1000000> micro;
284
  typedef ratio<1,                      1000> milli;
285
  typedef ratio<1,                       100> centi;
286
  typedef ratio<1,                        10> deci;
287
  typedef ratio<                       10, 1> deca;
288
  typedef ratio<                      100, 1> hecto;
289
  typedef ratio<                     1000, 1> kilo;
290
  typedef ratio<                  1000000, 1> mega;
291
  typedef ratio<               1000000000, 1> giga;
292
  typedef ratio<            1000000000000, 1> tera;
293
  typedef ratio<         1000000000000000, 1> peta;
294
  typedef ratio<      1000000000000000000, 1> exa;
295
 
296
  // @} group ratio
297
}
298
 
299
#endif //_GLIBCXX_USE_C99_STDINT_TR1
300
 
301
#endif //__GXX_EXPERIMENTAL_CXX0X__
302
 
303
#endif //_GLIBCXX_RATIO

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.