1 | // -*- C++ -*- |
---|
2 | // $Id$ |
---|
3 | |
---|
4 | /* |
---|
5 | * Copyright (c) 1997 |
---|
6 | * Silicon Graphics Computer Systems, Inc. |
---|
7 | * |
---|
8 | * Permission to use, copy, modify, distribute and sell this software |
---|
9 | * and its documentation for any purpose is hereby granted without fee, |
---|
10 | * provided that the above copyright notice appear in all copies and |
---|
11 | * that both that copyright notice and this permission notice appear |
---|
12 | * in supporting documentation. Silicon Graphics makes no |
---|
13 | * representations about the suitability of this software for any |
---|
14 | * purpose. It is provided "as is" without express or implied warranty. |
---|
15 | */ |
---|
16 | |
---|
17 | /* NOTE: This is not portable code. Parts of numeric_limits<> are |
---|
18 | * inherently machine-dependent, and this file is written for the MIPS |
---|
19 | * architecture and the SGI MIPSpro C++ compiler. Parts of it (in |
---|
20 | * particular, some of the characteristics of floating-point types) |
---|
21 | * are almost certainly incorrect for any other platform. |
---|
22 | */ |
---|
23 | |
---|
24 | #include <blitz/wrap-climits.h> |
---|
25 | #include <float.h> |
---|
26 | |
---|
27 | BZ_NAMESPACE(std) |
---|
28 | |
---|
29 | enum float_round_style { |
---|
30 | round_indeterminate = -1, |
---|
31 | round_toward_zero = 0, |
---|
32 | round_to_nearest = 1, |
---|
33 | round_toward_infinity = 2, |
---|
34 | round_toward_neg_infinity = 3 |
---|
35 | }; |
---|
36 | |
---|
37 | enum float_denorm_style { |
---|
38 | denorm_indeterminate = -1, |
---|
39 | denorm_absent = 0, |
---|
40 | denorm_present = 1 |
---|
41 | }; |
---|
42 | |
---|
43 | // Base class for all specializations of numeric_limits. |
---|
44 | |
---|
45 | template <typename __number> |
---|
46 | class _Numeric_limits_base { |
---|
47 | public: |
---|
48 | static const bool is_specialized = false; |
---|
49 | |
---|
50 | static __number (min)() { return __number(); } |
---|
51 | static __number (max)() { return __number(); } |
---|
52 | |
---|
53 | static const int digits = 0; |
---|
54 | static const int digits10 = 0; |
---|
55 | |
---|
56 | static const bool is_signed = false; |
---|
57 | static const bool is_integer = false; |
---|
58 | static const bool is_exact = false; |
---|
59 | |
---|
60 | static const int radix = 0; |
---|
61 | |
---|
62 | static __number epsilon() { return __number(); } |
---|
63 | static __number round_error() { return __number(); } |
---|
64 | |
---|
65 | static const int min_exponent = 0; |
---|
66 | static const int min_exponent10 = 0; |
---|
67 | static const int max_exponent = 0; |
---|
68 | static const int max_exponent10 = 0; |
---|
69 | |
---|
70 | static const bool has_infinity = false; |
---|
71 | static const bool has_quiet_NaN = false; |
---|
72 | static const bool has_signaling_NaN = false; |
---|
73 | static const float_denorm_style has_denorm = denorm_absent; |
---|
74 | static const bool has_denorm_loss = false; |
---|
75 | |
---|
76 | static __number infinity() { return __number(); } |
---|
77 | static __number quiet_NaN() { return __number(); } |
---|
78 | static __number signaling_NaN() { return __number(); } |
---|
79 | static __number denorm_min() { return __number(); } |
---|
80 | |
---|
81 | static const bool is_iec559 = false; |
---|
82 | static const bool is_bounded = false; |
---|
83 | static const bool is_modulo = false; |
---|
84 | |
---|
85 | static const bool traps = false; |
---|
86 | static const bool tinyness_before = false; |
---|
87 | static const float_round_style round_style = round_toward_zero; |
---|
88 | }; |
---|
89 | |
---|
90 | #define __declare_numeric_base_member(__type, __mem) \ |
---|
91 | template <typename __number> \ |
---|
92 | const __type _Numeric_limits_base<__number>:: __mem |
---|
93 | |
---|
94 | __declare_numeric_base_member(bool, is_specialized); |
---|
95 | __declare_numeric_base_member(int, digits); |
---|
96 | __declare_numeric_base_member(int, digits10); |
---|
97 | __declare_numeric_base_member(bool, is_signed); |
---|
98 | __declare_numeric_base_member(bool, is_integer); |
---|
99 | __declare_numeric_base_member(bool, is_exact); |
---|
100 | __declare_numeric_base_member(int, radix); |
---|
101 | __declare_numeric_base_member(int, min_exponent); |
---|
102 | __declare_numeric_base_member(int, max_exponent); |
---|
103 | __declare_numeric_base_member(int, min_exponent10); |
---|
104 | __declare_numeric_base_member(int, max_exponent10); |
---|
105 | __declare_numeric_base_member(bool, has_infinity); |
---|
106 | __declare_numeric_base_member(bool, has_quiet_NaN); |
---|
107 | __declare_numeric_base_member(bool, has_signaling_NaN); |
---|
108 | __declare_numeric_base_member(float_denorm_style, has_denorm); |
---|
109 | __declare_numeric_base_member(bool, has_denorm_loss); |
---|
110 | __declare_numeric_base_member(bool, is_iec559); |
---|
111 | __declare_numeric_base_member(bool, is_bounded); |
---|
112 | __declare_numeric_base_member(bool, is_modulo); |
---|
113 | __declare_numeric_base_member(bool, traps); |
---|
114 | __declare_numeric_base_member(bool, tinyness_before); |
---|
115 | __declare_numeric_base_member(float_round_style, round_style); |
---|
116 | |
---|
117 | #undef __declare_numeric_base_member |
---|
118 | |
---|
119 | // Base class for integers. |
---|
120 | |
---|
121 | template <typename _Int, |
---|
122 | _Int __imin, |
---|
123 | _Int __imax, |
---|
124 | int __idigits = -1> |
---|
125 | class _Integer_limits : public _Numeric_limits_base<_Int> { |
---|
126 | public: |
---|
127 | static const bool is_specialized = true; |
---|
128 | |
---|
129 | static _Int (min)() { return __imin; } |
---|
130 | static _Int (max)() { return __imax; } |
---|
131 | |
---|
132 | static const int digits = |
---|
133 | (__idigits < 0) ? sizeof(_Int) * CHAR_BIT - (__imin == 0 ? 0 : 1) |
---|
134 | : __idigits; |
---|
135 | static const int digits10 = (digits * 301) / 1000; |
---|
136 | // log 2 = 0.301029995664... |
---|
137 | |
---|
138 | static const bool is_signed = __imin != 0; |
---|
139 | static const bool is_integer = true; |
---|
140 | static const bool is_exact = true; |
---|
141 | static const int radix = 2; |
---|
142 | |
---|
143 | |
---|
144 | static const bool is_bounded = true; |
---|
145 | static const bool is_modulo = true; |
---|
146 | }; |
---|
147 | |
---|
148 | #define __declare_integer_limits_member(__type, __mem) \ |
---|
149 | template <typename _Int, _Int __imin, _Int __imax, int __idigits> \ |
---|
150 | const __type _Integer_limits<_Int, __imin, __imax, __idigits>:: __mem |
---|
151 | |
---|
152 | __declare_integer_limits_member(bool, is_specialized); |
---|
153 | __declare_integer_limits_member(int, digits); |
---|
154 | __declare_integer_limits_member(int, digits10); |
---|
155 | __declare_integer_limits_member(bool, is_signed); |
---|
156 | __declare_integer_limits_member(bool, is_integer); |
---|
157 | __declare_integer_limits_member(bool, is_exact); |
---|
158 | __declare_integer_limits_member(int, radix); |
---|
159 | __declare_integer_limits_member(bool, is_bounded); |
---|
160 | __declare_integer_limits_member(bool, is_modulo); |
---|
161 | |
---|
162 | #undef __declare_integer_limits_member |
---|
163 | |
---|
164 | // Base class for floating-point numbers. |
---|
165 | template <typename __number, |
---|
166 | int __Digits, int __Digits10, |
---|
167 | int __MinExp, int __MaxExp, |
---|
168 | int __MinExp10, int __MaxExp10, |
---|
169 | unsigned int __InfinityWord, |
---|
170 | unsigned int __QNaNWord, unsigned int __SNaNWord, |
---|
171 | bool __IsIEC559, |
---|
172 | float_round_style __RoundStyle> |
---|
173 | class _Floating_limits : public _Numeric_limits_base<__number> |
---|
174 | { |
---|
175 | public: |
---|
176 | static const bool is_specialized = true; |
---|
177 | |
---|
178 | static const int digits = __Digits; |
---|
179 | static const int digits10 = __Digits10; |
---|
180 | |
---|
181 | static const bool is_signed = true; |
---|
182 | |
---|
183 | static const int radix = 2; |
---|
184 | |
---|
185 | static const int min_exponent = __MinExp; |
---|
186 | static const int max_exponent = __MaxExp; |
---|
187 | static const int min_exponent10 = __MinExp10; |
---|
188 | static const int max_exponent10 = __MaxExp10; |
---|
189 | |
---|
190 | static const bool has_infinity = true; |
---|
191 | static const bool has_quiet_NaN = true; |
---|
192 | static const bool has_signaling_NaN = true; |
---|
193 | static const float_denorm_style has_denorm = denorm_indeterminate; |
---|
194 | static const bool has_denorm_loss = false; |
---|
195 | |
---|
196 | static __number infinity() { |
---|
197 | static unsigned int _S_inf[sizeof(__number) / sizeof(int)] = |
---|
198 | { __InfinityWord }; |
---|
199 | return *reinterpret_cast<__number*>(&_S_inf); |
---|
200 | } |
---|
201 | static __number quiet_NaN() { |
---|
202 | static unsigned int _S_nan[sizeof(__number) / sizeof(int)] = |
---|
203 | { __QNaNWord }; |
---|
204 | return *reinterpret_cast<__number*>(&_S_nan); |
---|
205 | } |
---|
206 | static __number signaling_NaN() { |
---|
207 | static unsigned int _S_nan[sizeof(__number) / sizeof(int)] = |
---|
208 | { __SNaNWord }; |
---|
209 | return *reinterpret_cast<__number*>(&_S_nan); |
---|
210 | } |
---|
211 | |
---|
212 | static const bool is_iec559 = __IsIEC559; |
---|
213 | static const bool is_bounded = true; |
---|
214 | static const bool traps = true; |
---|
215 | static const bool tinyness_before = false; |
---|
216 | |
---|
217 | static const float_round_style round_style = __RoundStyle; |
---|
218 | }; |
---|
219 | |
---|
220 | #define __declare_float_limits_member(__type, __mem) \ |
---|
221 | template <typename __Num, int __Dig, int __Dig10, \ |
---|
222 | int __MnX, int __MxX, int __MnX10, int __MxX10, \ |
---|
223 | unsigned int __Inf, unsigned int __QNaN, unsigned int __SNaN, \ |
---|
224 | bool __IsIEEE, float_round_style __Sty> \ |
---|
225 | const __type _Floating_limits<__Num, __Dig, __Dig10, \ |
---|
226 | __MnX, __MxX, __MnX10, __MxX10, \ |
---|
227 | __Inf, __QNaN, __SNaN,__IsIEEE, __Sty>:: __mem |
---|
228 | |
---|
229 | __declare_float_limits_member(bool, is_specialized); |
---|
230 | __declare_float_limits_member(int, digits); |
---|
231 | __declare_float_limits_member(int, digits10); |
---|
232 | __declare_float_limits_member(bool, is_signed); |
---|
233 | __declare_float_limits_member(int, radix); |
---|
234 | __declare_float_limits_member(int, min_exponent); |
---|
235 | __declare_float_limits_member(int, max_exponent); |
---|
236 | __declare_float_limits_member(int, min_exponent10); |
---|
237 | __declare_float_limits_member(int, max_exponent10); |
---|
238 | __declare_float_limits_member(bool, has_infinity); |
---|
239 | __declare_float_limits_member(bool, has_quiet_NaN); |
---|
240 | __declare_float_limits_member(bool, has_signaling_NaN); |
---|
241 | __declare_float_limits_member(float_denorm_style, has_denorm); |
---|
242 | __declare_float_limits_member(bool, has_denorm_loss); |
---|
243 | __declare_float_limits_member(bool, is_iec559); |
---|
244 | __declare_float_limits_member(bool, is_bounded); |
---|
245 | __declare_float_limits_member(bool, traps); |
---|
246 | __declare_float_limits_member(bool, tinyness_before); |
---|
247 | __declare_float_limits_member(float_round_style, round_style); |
---|
248 | |
---|
249 | #undef __declare_float_limits_member |
---|
250 | |
---|
251 | // Class numeric_limits |
---|
252 | |
---|
253 | // The unspecialized class. |
---|
254 | |
---|
255 | template<typename T> |
---|
256 | class numeric_limits : public _Numeric_limits_base<T> {}; |
---|
257 | |
---|
258 | // Specializations for all built-in integral types. |
---|
259 | |
---|
260 | #ifndef __STL_NO_BOOL |
---|
261 | |
---|
262 | template<> |
---|
263 | class numeric_limits<bool> |
---|
264 | : public _Integer_limits<bool, false, true, 0> {}; |
---|
265 | |
---|
266 | #endif /* __STL_NO_BOOL */ |
---|
267 | |
---|
268 | template<> |
---|
269 | class numeric_limits<char> |
---|
270 | : public _Integer_limits<char, CHAR_MIN, CHAR_MAX> {}; |
---|
271 | |
---|
272 | template<> |
---|
273 | class numeric_limits<signed char> |
---|
274 | : public _Integer_limits<signed char, SCHAR_MIN, SCHAR_MAX> {}; |
---|
275 | |
---|
276 | template<> |
---|
277 | class numeric_limits<unsigned char> |
---|
278 | : public _Integer_limits<unsigned char, 0, UCHAR_MAX> {}; |
---|
279 | |
---|
280 | #ifdef __STL_HAS_WCHAR_T |
---|
281 | |
---|
282 | template<> |
---|
283 | class numeric_limits<wchar_t> |
---|
284 | : public _Integer_limits<wchar_t, INT_MIN, INT_MAX> {}; |
---|
285 | |
---|
286 | #endif |
---|
287 | |
---|
288 | template<> |
---|
289 | class numeric_limits<short> |
---|
290 | : public _Integer_limits<short, SHRT_MIN, SHRT_MAX> {}; |
---|
291 | |
---|
292 | template<> |
---|
293 | class numeric_limits<unsigned short> |
---|
294 | : public _Integer_limits<unsigned short, 0, USHRT_MAX> {}; |
---|
295 | |
---|
296 | template<> |
---|
297 | class numeric_limits<int> |
---|
298 | : public _Integer_limits<int, INT_MIN, INT_MAX> {}; |
---|
299 | |
---|
300 | template<> |
---|
301 | class numeric_limits<unsigned int> |
---|
302 | : public _Integer_limits<unsigned int, 0, UINT_MAX> {}; |
---|
303 | |
---|
304 | template<> |
---|
305 | class numeric_limits<long> |
---|
306 | : public _Integer_limits<long, LONG_MIN, LONG_MAX> {}; |
---|
307 | |
---|
308 | template<> |
---|
309 | class numeric_limits<unsigned long> |
---|
310 | : public _Integer_limits<unsigned long, 0, ULONG_MAX> {}; |
---|
311 | |
---|
312 | #ifdef __STL_LONG_LONG |
---|
313 | #ifdef LONG_LONG_MIN |
---|
314 | |
---|
315 | // CYGNUS LOCAL 9/4/1998 |
---|
316 | // fixed LONGLONG to be LONG_LONG |
---|
317 | template<> |
---|
318 | class numeric_limits<long long> |
---|
319 | : public _Integer_limits<long long, LONG_LONG_MIN, LONG_LONG_MAX> {}; |
---|
320 | |
---|
321 | // CYGNUS LOCAL 9/4/1998 |
---|
322 | // fixed LONGLONG to be LONG_LONG |
---|
323 | template<> |
---|
324 | class numeric_limits<unsigned long long> |
---|
325 | : public _Integer_limits<unsigned long long, 0, ULONG_LONG_MAX> {}; |
---|
326 | |
---|
327 | #endif |
---|
328 | #endif /* __STL_LONG_LONG */ |
---|
329 | |
---|
330 | // Specializations for all built-in floating-point type. |
---|
331 | |
---|
332 | template<> class numeric_limits<float> |
---|
333 | : public _Floating_limits<float, |
---|
334 | FLT_MANT_DIG, // Binary digits of precision |
---|
335 | FLT_DIG, // Decimal digits of precision |
---|
336 | FLT_MIN_EXP, // Minimum exponent |
---|
337 | FLT_MAX_EXP, // Maximum exponent |
---|
338 | FLT_MIN_10_EXP, // Minimum base 10 exponent |
---|
339 | FLT_MAX_10_EXP, // Maximum base 10 exponent |
---|
340 | 0x7f800000u, // First word of +infinity |
---|
341 | 0x7f810000u, // First word of quiet NaN |
---|
342 | 0x7fc10000u, // First word of signaling NaN |
---|
343 | true, // conforms to iec559 |
---|
344 | round_to_nearest> |
---|
345 | { |
---|
346 | public: |
---|
347 | static float (min)() { return FLT_MIN; } |
---|
348 | static float denorm_min() { return FLT_MIN; } |
---|
349 | static float (max)() { return FLT_MAX; } |
---|
350 | static float epsilon() { return FLT_EPSILON; } |
---|
351 | static float round_error() { return 0.5f; } // Units: ulps. |
---|
352 | }; |
---|
353 | |
---|
354 | template<> class numeric_limits<double> |
---|
355 | : public _Floating_limits<double, |
---|
356 | DBL_MANT_DIG, // Binary digits of precision |
---|
357 | DBL_DIG, // Decimal digits of precision |
---|
358 | DBL_MIN_EXP, // Minimum exponent |
---|
359 | DBL_MAX_EXP, // Maximum exponent |
---|
360 | DBL_MIN_10_EXP, // Minimum base 10 exponent |
---|
361 | DBL_MAX_10_EXP, // Maximum base 10 exponent |
---|
362 | 0x7ff00000u, // First word of +infinity |
---|
363 | 0x7ff10000u, // First word of quiet NaN |
---|
364 | 0x7ff90000u, // First word of signaling NaN |
---|
365 | true, // conforms to iec559 |
---|
366 | round_to_nearest> |
---|
367 | { |
---|
368 | public: |
---|
369 | static double (min)() { return DBL_MIN; } |
---|
370 | static double denorm_min() { return DBL_MIN; } |
---|
371 | static double (max)() { return DBL_MAX; } |
---|
372 | static double epsilon() { return DBL_EPSILON; } |
---|
373 | static double round_error() { return 0.5; } // Units: ulps. |
---|
374 | }; |
---|
375 | |
---|
376 | template<> class numeric_limits<long double> |
---|
377 | : public _Floating_limits<long double, |
---|
378 | LDBL_MANT_DIG, // Binary digits of precision |
---|
379 | LDBL_DIG, // Decimal digits of precision |
---|
380 | LDBL_MIN_EXP, // Minimum exponent |
---|
381 | LDBL_MAX_EXP, // Maximum exponent |
---|
382 | LDBL_MIN_10_EXP,// Minimum base 10 exponent |
---|
383 | LDBL_MAX_10_EXP,// Maximum base 10 exponent |
---|
384 | 0x7ff00000u, // First word of +infinity |
---|
385 | 0x7ff10000u, // First word of quiet NaN |
---|
386 | 0x7ff90000u, // First word of signaling NaN |
---|
387 | false, // Doesn't conform to iec559 |
---|
388 | round_to_nearest> |
---|
389 | { |
---|
390 | public: |
---|
391 | static long double (min)() { return LDBL_MIN; } |
---|
392 | static long double denorm_min() { return LDBL_MIN; } |
---|
393 | static long double (max)() { return LDBL_MAX; } |
---|
394 | static long double epsilon() { return LDBL_EPSILON; } |
---|
395 | static long double round_error() { return 4; } // Units: ulps. |
---|
396 | }; |
---|
397 | |
---|
398 | BZ_NAMESPACE_END |
---|
399 | |
---|