1 | /////////////////////////////////////////////////////////////// |
2 | // Copyright 2013 John Maddock. Distributed under the Boost |
3 | // Software License, Version 1.0. (See accompanying file |
4 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_ |
5 | |
6 | #ifndef BOOST_MP_FLOAT128_HPP |
7 | #define BOOST_MP_FLOAT128_HPP |
8 | |
9 | #include <boost/config.hpp> |
10 | #include <boost/scoped_array.hpp> |
11 | #include <boost/multiprecision/number.hpp> |
12 | |
13 | #if defined(BOOST_INTEL) && !defined(BOOST_MP_USE_FLOAT128) && !defined(BOOST_MP_USE_QUAD) |
14 | # if defined(BOOST_INTEL_CXX_VERSION) && (BOOST_INTEL_CXX_VERSION >= 1310) && defined(__GNUC__) |
15 | # if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) |
16 | # define BOOST_MP_USE_FLOAT128 |
17 | # endif |
18 | # endif |
19 | |
20 | # ifndef BOOST_MP_USE_FLOAT128 |
21 | # define BOOST_MP_USE_QUAD |
22 | # endif |
23 | #endif |
24 | |
25 | #if defined(__GNUC__) && !defined(BOOST_MP_USE_FLOAT128) && !defined(BOOST_MP_USE_QUAD) |
26 | # define BOOST_MP_USE_FLOAT128 |
27 | #endif |
28 | |
29 | #if !defined(BOOST_MP_USE_FLOAT128) && !defined(BOOST_MP_USE_QUAD) |
30 | # error "Sorry compiler is neither GCC, not Intel, don't know how to configure this header." |
31 | #endif |
32 | #if defined(BOOST_MP_USE_FLOAT128) && defined(BOOST_MP_USE_QUAD) |
33 | # error "Oh dear, both BOOST_MP_USE_FLOAT128 and BOOST_MP_USE_QUAD are defined, which one should I be using?" |
34 | #endif |
35 | |
36 | #if defined(BOOST_MP_USE_FLOAT128) |
37 | |
38 | extern "C" { |
39 | #include <quadmath.h> |
40 | } |
41 | |
42 | typedef __float128 float128_type; |
43 | |
44 | #elif defined(BOOST_MP_USE_QUAD) |
45 | |
46 | #include <boost/multiprecision/detail/float_string_cvt.hpp> |
47 | |
48 | typedef _Quad float128_type; |
49 | |
50 | extern "C" { |
51 | _Quad __ldexpq(_Quad, int); |
52 | _Quad __frexpq(_Quad, int*); |
53 | _Quad __fabsq(_Quad); |
54 | _Quad __floorq(_Quad); |
55 | _Quad __ceilq(_Quad); |
56 | _Quad __sqrtq(_Quad); |
57 | _Quad __truncq(_Quad); |
58 | _Quad __expq(_Quad); |
59 | _Quad __powq(_Quad, _Quad); |
60 | _Quad __logq(_Quad); |
61 | _Quad __log10q(_Quad); |
62 | _Quad __sinq(_Quad); |
63 | _Quad __cosq(_Quad); |
64 | _Quad __tanq(_Quad); |
65 | _Quad __asinq(_Quad); |
66 | _Quad __acosq(_Quad); |
67 | _Quad __atanq(_Quad); |
68 | _Quad __sinhq(_Quad); |
69 | _Quad __coshq(_Quad); |
70 | _Quad __tanhq(_Quad); |
71 | _Quad __fmodq(_Quad, _Quad); |
72 | _Quad __atan2q(_Quad, _Quad); |
73 | |
74 | #define ldexpq __ldexpq |
75 | #define frexpq __frexpq |
76 | #define fabsq __fabsq |
77 | #define floorq __floorq |
78 | #define ceilq __ceilq |
79 | #define sqrtq __sqrtq |
80 | #define truncq __truncq |
81 | #define expq __expq |
82 | #define powq __powq |
83 | #define logq __logq |
84 | #define log10q __log10q |
85 | #define sinq __sinq |
86 | #define cosq __cosq |
87 | #define tanq __tanq |
88 | #define asinq __asinq |
89 | #define acosq __acosq |
90 | #define atanq __atanq |
91 | #define sinhq __sinhq |
92 | #define coshq __coshq |
93 | #define tanhq __tanhq |
94 | #define fmodq __fmodq |
95 | #define atan2q __atan2q |
96 | } |
97 | |
98 | inline _Quad isnanq(_Quad v) |
99 | { |
100 | return v != v; |
101 | } |
102 | inline _Quad isinfq(_Quad v) |
103 | { |
104 | return __fabsq(v) > 1.18973149535723176508575932662800702e4932Q; |
105 | } |
106 | |
107 | #endif |
108 | |
109 | namespace boost{ |
110 | namespace multiprecision{ |
111 | namespace backends{ |
112 | |
113 | struct float128_backend; |
114 | |
115 | } |
116 | |
117 | using backends::float128_backend; |
118 | |
119 | template<> |
120 | struct number_category<backends::float128_backend> : public mpl::int_<number_kind_floating_point> {}; |
121 | template<> |
122 | struct number_category<float128_type> : public mpl::int_<number_kind_floating_point> {}; |
123 | |
124 | typedef number<float128_backend, et_off> float128; |
125 | |
126 | namespace backends{ |
127 | |
128 | struct float128_backend |
129 | { |
130 | typedef mpl::list<signed char, short, int, long, boost::long_long_type> signed_types; |
131 | typedef mpl::list<unsigned char, unsigned short, |
132 | unsigned int, unsigned long, boost::ulong_long_type> unsigned_types; |
133 | typedef mpl::list<float, double, long double> float_types; |
134 | typedef int exponent_type; |
135 | |
136 | private: |
137 | float128_type m_value; |
138 | public: |
139 | BOOST_CONSTEXPR float128_backend() BOOST_NOEXCEPT : m_value(0) {} |
140 | BOOST_CONSTEXPR float128_backend(const float128_backend& o) BOOST_NOEXCEPT : m_value(o.m_value) {} |
141 | float128_backend& operator = (const float128_backend& o) BOOST_NOEXCEPT |
142 | { |
143 | m_value = o.m_value; |
144 | return *this; |
145 | } |
146 | template <class T> |
147 | BOOST_CONSTEXPR float128_backend(const T& i, const typename enable_if_c<is_convertible<T, float128_type>::value>::type* = 0) BOOST_NOEXCEPT_IF(noexcept(std::declval<float128_type&>() = std::declval<const T&>())) |
148 | : m_value(i) {} |
149 | template <class T> |
150 | typename enable_if_c<is_arithmetic<T>::value || is_convertible<T, float128_type>::value, float128_backend&>::type operator = (const T& i) BOOST_NOEXCEPT_IF(noexcept(std::declval<float128_type&>() = std::declval<const T&>())) |
151 | { |
152 | m_value = i; |
153 | return *this; |
154 | } |
155 | float128_backend& operator = (const char* s) |
156 | { |
157 | #ifndef BOOST_MP_USE_QUAD |
158 | char* p_end; |
159 | m_value = strtoflt128(s, &p_end); |
160 | if(p_end - s != (std::ptrdiff_t)std::strlen(s: s)) |
161 | { |
162 | BOOST_THROW_EXCEPTION(std::runtime_error("Unable to interpret input string as a floating point value" )); |
163 | } |
164 | #else |
165 | boost::multiprecision::detail::convert_from_string(*this, s); |
166 | #endif |
167 | return *this; |
168 | } |
169 | void swap(float128_backend& o) BOOST_NOEXCEPT |
170 | { |
171 | std::swap(m_value, o.value()); |
172 | } |
173 | std::string str(std::streamsize digits, std::ios_base::fmtflags f)const |
174 | { |
175 | #ifndef BOOST_MP_USE_QUAD |
176 | char buf[100]; |
177 | boost::scoped_array<char> buf2; |
178 | std::string format = "%" ; |
179 | if(f & std::ios_base::showpos) |
180 | format += "+" ; |
181 | if(f & std::ios_base::showpoint) |
182 | format += "#" ; |
183 | format += ".*" ; |
184 | if(digits == 0) |
185 | digits = 36; |
186 | format += "Q" ; |
187 | if(f & std::ios_base::scientific) |
188 | format += "e" ; |
189 | else if(f & std::ios_base::fixed) |
190 | format += "f" ; |
191 | else |
192 | format += "g" ; |
193 | |
194 | int v = quadmath_snprintf (buf, 100, format.c_str(), digits, m_value); |
195 | |
196 | if((v < 0) || (v >= 99)) |
197 | { |
198 | int v_max = v; |
199 | buf2.reset(new char[v+3]); |
200 | v = quadmath_snprintf (&buf2[0], v_max + 3, format.c_str(), digits, m_value); |
201 | if(v >= v_max + 3) |
202 | { |
203 | BOOST_THROW_EXCEPTION(std::runtime_error("Formatting of float128_type failed." )); |
204 | } |
205 | return &buf2[0]; |
206 | } |
207 | return buf; |
208 | #else |
209 | return boost::multiprecision::detail::convert_to_string(*this, digits ? digits : 37, f); |
210 | #endif |
211 | } |
212 | void negate() BOOST_NOEXCEPT |
213 | { |
214 | m_value = -m_value; |
215 | } |
216 | int compare(const float128_backend& o)const |
217 | { |
218 | return m_value == o.m_value ? 0 : m_value < o.m_value ? -1 : 1; |
219 | } |
220 | template <class T> |
221 | int compare(const T& i)const |
222 | { |
223 | return m_value == i ? 0 : m_value < i ? -1 : 1; |
224 | } |
225 | float128_type& value() |
226 | { |
227 | return m_value; |
228 | } |
229 | const float128_type& value()const |
230 | { |
231 | return m_value; |
232 | } |
233 | }; |
234 | |
235 | inline void eval_add(float128_backend& result, const float128_backend& a) |
236 | { |
237 | result.value() += a.value(); |
238 | } |
239 | template <class A> |
240 | inline void eval_add(float128_backend& result, const A& a) |
241 | { |
242 | result.value() += a; |
243 | } |
244 | inline void eval_subtract(float128_backend& result, const float128_backend& a) |
245 | { |
246 | result.value() -= a.value(); |
247 | } |
248 | template <class A> |
249 | inline void eval_subtract(float128_backend& result, const A& a) |
250 | { |
251 | result.value() -= a; |
252 | } |
253 | inline void eval_multiply(float128_backend& result, const float128_backend& a) |
254 | { |
255 | result.value() *= a.value(); |
256 | } |
257 | template <class A> |
258 | inline void eval_multiply(float128_backend& result, const A& a) |
259 | { |
260 | result.value() *= a; |
261 | } |
262 | inline void eval_divide(float128_backend& result, const float128_backend& a) |
263 | { |
264 | result.value() /= a.value(); |
265 | } |
266 | template <class A> |
267 | inline void eval_divide(float128_backend& result, const A& a) |
268 | { |
269 | result.value() /= a; |
270 | } |
271 | |
272 | inline void eval_add(float128_backend& result, const float128_backend& a, const float128_backend& b) |
273 | { |
274 | result.value() = a.value() + b.value(); |
275 | } |
276 | template <class A> |
277 | inline void eval_add(float128_backend& result, const float128_backend& a, const A& b) |
278 | { |
279 | result.value() = a.value() + b; |
280 | } |
281 | inline void eval_subtract(float128_backend& result, const float128_backend& a, const float128_backend& b) |
282 | { |
283 | result.value() = a.value() - b.value(); |
284 | } |
285 | template <class A> |
286 | inline void eval_subtract(float128_backend& result, const float128_backend& a, const A& b) |
287 | { |
288 | result.value() = a.value() - b; |
289 | } |
290 | template <class A> |
291 | inline void eval_subtract(float128_backend& result, const A& a, const float128_backend& b) |
292 | { |
293 | result.value() = a - b.value(); |
294 | } |
295 | inline void eval_multiply(float128_backend& result, const float128_backend& a, const float128_backend& b) |
296 | { |
297 | result.value() = a.value() * b.value(); |
298 | } |
299 | template <class A> |
300 | inline void eval_multiply(float128_backend& result, const float128_backend& a, const A& b) |
301 | { |
302 | result.value() = a.value() * b; |
303 | } |
304 | inline void eval_divide(float128_backend& result, const float128_backend& a, const float128_backend& b) |
305 | { |
306 | result.value() = a.value() / b.value(); |
307 | } |
308 | |
309 | template <class R> |
310 | inline void eval_convert_to(R* result, const float128_backend& val) |
311 | { |
312 | *result = static_cast<R>(val.value()); |
313 | } |
314 | |
315 | inline void eval_frexp(float128_backend& result, const float128_backend& arg, int* exp) |
316 | { |
317 | result.value() = frexpq(arg.value(), exp); |
318 | } |
319 | |
320 | inline void eval_ldexp(float128_backend& result, const float128_backend& arg, int exp) |
321 | { |
322 | result.value() = ldexpq(arg.value(), exp); |
323 | } |
324 | |
325 | inline void eval_floor(float128_backend& result, const float128_backend& arg) |
326 | { |
327 | result.value() = floorq(arg.value()); |
328 | } |
329 | inline void eval_ceil(float128_backend& result, const float128_backend& arg) |
330 | { |
331 | result.value() = ceilq(arg.value()); |
332 | } |
333 | inline void eval_sqrt(float128_backend& result, const float128_backend& arg) |
334 | { |
335 | result.value() = sqrtq(arg.value()); |
336 | } |
337 | inline int eval_fpclassify(const float128_backend& arg) |
338 | { |
339 | return isnanq(arg.value()) ? FP_NAN : isinfq(arg.value()) ? FP_INFINITE : arg.value() == 0 ? FP_ZERO : FP_NORMAL; |
340 | } |
341 | |
342 | inline void eval_increment(float128_backend& arg) |
343 | { |
344 | ++arg.value(); |
345 | } |
346 | inline void eval_decrement(float128_backend& arg) |
347 | { |
348 | --arg.value(); |
349 | } |
350 | |
351 | /********************************************************************* |
352 | * |
353 | * abs/fabs: |
354 | * |
355 | *********************************************************************/ |
356 | |
357 | inline void eval_abs(float128_backend& result, const float128_backend& arg) |
358 | { |
359 | result.value() = fabsq(arg.value()); |
360 | } |
361 | inline void eval_fabs(float128_backend& result, const float128_backend& arg) |
362 | { |
363 | result.value() = fabsq(arg.value()); |
364 | } |
365 | |
366 | /********************************************************************* |
367 | * |
368 | * Floating point functions: |
369 | * |
370 | *********************************************************************/ |
371 | |
372 | inline void eval_trunc(float128_backend& result, const float128_backend& arg) |
373 | { |
374 | if(isnanq(arg.value()) || isinfq(arg.value())) |
375 | { |
376 | result = boost::math::policies::raise_rounding_error( |
377 | "boost::multiprecision::trunc<%1%>(%1%)" , 0, |
378 | number<float128_backend, et_off>(arg), |
379 | number<float128_backend, et_off>(arg), |
380 | boost::math::policies::policy<>()).backend(); |
381 | return; |
382 | } |
383 | result.value() = truncq(arg.value()); |
384 | } |
385 | /* |
386 | // |
387 | // This doesn't actually work... rely on our own default version instead. |
388 | // |
389 | inline void eval_round(float128_backend& result, const float128_backend& arg) |
390 | { |
391 | if(isnanq(arg.value()) || isinf(arg.value())) |
392 | { |
393 | result = boost::math::policies::raise_rounding_error( |
394 | "boost::multiprecision::trunc<%1%>(%1%)", 0, |
395 | number<float128_backend, et_off>(arg), |
396 | number<float128_backend, et_off>(arg), |
397 | boost::math::policies::policy<>()).backend(); |
398 | return; |
399 | } |
400 | result.value() = roundq(arg.value()); |
401 | } |
402 | */ |
403 | |
404 | inline void eval_exp(float128_backend& result, const float128_backend& arg) |
405 | { |
406 | result.value() = expq(arg.value()); |
407 | } |
408 | inline void eval_log(float128_backend& result, const float128_backend& arg) |
409 | { |
410 | result.value() = logq(arg.value()); |
411 | } |
412 | inline void eval_log10(float128_backend& result, const float128_backend& arg) |
413 | { |
414 | result.value() = log10q(arg.value()); |
415 | } |
416 | inline void eval_sin(float128_backend& result, const float128_backend& arg) |
417 | { |
418 | result.value() = sinq(arg.value()); |
419 | } |
420 | inline void eval_cos(float128_backend& result, const float128_backend& arg) |
421 | { |
422 | result.value() = cosq(arg.value()); |
423 | } |
424 | inline void eval_tan(float128_backend& result, const float128_backend& arg) |
425 | { |
426 | result.value() = tanq(arg.value()); |
427 | } |
428 | inline void eval_asin(float128_backend& result, const float128_backend& arg) |
429 | { |
430 | result.value() = asinq(arg.value()); |
431 | } |
432 | inline void eval_acos(float128_backend& result, const float128_backend& arg) |
433 | { |
434 | result.value() = acosq(arg.value()); |
435 | } |
436 | inline void eval_atan(float128_backend& result, const float128_backend& arg) |
437 | { |
438 | result.value() = atanq(arg.value()); |
439 | } |
440 | inline void eval_sinh(float128_backend& result, const float128_backend& arg) |
441 | { |
442 | result.value() = sinhq(arg.value()); |
443 | } |
444 | inline void eval_cosh(float128_backend& result, const float128_backend& arg) |
445 | { |
446 | result.value() = coshq(arg.value()); |
447 | } |
448 | inline void eval_tanh(float128_backend& result, const float128_backend& arg) |
449 | { |
450 | result.value() = tanhq(arg.value()); |
451 | } |
452 | inline void eval_fmod(float128_backend& result, const float128_backend& a, const float128_backend& b) |
453 | { |
454 | result.value() = fmodq(a.value(), b.value()); |
455 | } |
456 | inline void eval_pow(float128_backend& result, const float128_backend& a, const float128_backend& b) |
457 | { |
458 | result.value() = powq(a.value(), b.value()); |
459 | } |
460 | inline void eval_atan2(float128_backend& result, const float128_backend& a, const float128_backend& b) |
461 | { |
462 | result.value() = atan2q(a.value(), b.value()); |
463 | } |
464 | |
465 | } // namespace backends |
466 | |
467 | }} // namespaces |
468 | |
469 | namespace boost{ |
470 | namespace archive{ |
471 | |
472 | class binary_oarchive; |
473 | class binary_iarchive; |
474 | |
475 | } |
476 | |
477 | namespace serialization{ namespace float128_detail{ |
478 | |
479 | template <class Archive> |
480 | void do_serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, const mpl::false_&, const mpl::false_&) |
481 | { |
482 | // saving |
483 | // non-binary |
484 | std::string s(val.str(digits: 0, f: std::ios_base::scientific)); |
485 | ar & s; |
486 | } |
487 | template <class Archive> |
488 | void do_serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, const mpl::true_&, const mpl::false_&) |
489 | { |
490 | // loading |
491 | // non-binary |
492 | std::string s; |
493 | ar & s; |
494 | val = s.c_str(); |
495 | } |
496 | |
497 | template <class Archive> |
498 | void do_serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, const mpl::false_&, const mpl::true_&) |
499 | { |
500 | // saving |
501 | // binary |
502 | ar.save_binary(&val, sizeof(val)); |
503 | } |
504 | template <class Archive> |
505 | void do_serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, const mpl::true_&, const mpl::true_&) |
506 | { |
507 | // loading |
508 | // binary |
509 | ar.load_binary(&val, sizeof(val)); |
510 | } |
511 | |
512 | } // detail |
513 | |
514 | template <class Archive> |
515 | void serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, unsigned int /*version*/) |
516 | { |
517 | typedef typename Archive::is_loading load_tag; |
518 | typedef typename mpl::bool_<boost::is_same<Archive, boost::archive::binary_oarchive>::value || boost::is_same<Archive, boost::archive::binary_iarchive>::value> binary_tag; |
519 | |
520 | float128_detail::do_serialize(ar, val, load_tag(), binary_tag()); |
521 | } |
522 | |
523 | }} |
524 | |
525 | namespace std{ |
526 | |
527 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
528 | class numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> > |
529 | { |
530 | typedef boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> number_type; |
531 | public: |
532 | BOOST_STATIC_CONSTEXPR bool is_specialized = true; |
533 | static number_type (min)() BOOST_NOEXCEPT { return 3.36210314311209350626267781732175260e-4932Q; } |
534 | static number_type (max)() BOOST_NOEXCEPT { return 1.18973149535723176508575932662800702e4932Q; } |
535 | static number_type lowest() BOOST_NOEXCEPT { return -(max)(); } |
536 | BOOST_STATIC_CONSTEXPR int digits = 113; |
537 | BOOST_STATIC_CONSTEXPR int digits10 = 33; |
538 | BOOST_STATIC_CONSTEXPR int max_digits10 = 36; |
539 | BOOST_STATIC_CONSTEXPR bool is_signed = true; |
540 | BOOST_STATIC_CONSTEXPR bool is_integer = false; |
541 | BOOST_STATIC_CONSTEXPR bool is_exact = false; |
542 | BOOST_STATIC_CONSTEXPR int radix = 2; |
543 | static number_type epsilon() { return 1.92592994438723585305597794258492732e-34Q; } |
544 | static number_type round_error() { return 0.5; } |
545 | BOOST_STATIC_CONSTEXPR int min_exponent = -16381; |
546 | BOOST_STATIC_CONSTEXPR int min_exponent10 = min_exponent * 301L / 1000L; |
547 | BOOST_STATIC_CONSTEXPR int max_exponent = 16384; |
548 | BOOST_STATIC_CONSTEXPR int max_exponent10 = max_exponent * 301L / 1000L; |
549 | BOOST_STATIC_CONSTEXPR bool has_infinity = true; |
550 | BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = true; |
551 | BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false; |
552 | BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent; |
553 | BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false; |
554 | static number_type infinity() { return 1.0q / 0.0q; } |
555 | static number_type quiet_NaN() { return number_type("nan" ); } |
556 | static number_type signaling_NaN() { return 0; } |
557 | static number_type denorm_min() { return 0; } |
558 | BOOST_STATIC_CONSTEXPR bool is_iec559 = true; |
559 | BOOST_STATIC_CONSTEXPR bool is_bounded = false; |
560 | BOOST_STATIC_CONSTEXPR bool is_modulo = false; |
561 | BOOST_STATIC_CONSTEXPR bool traps = false; |
562 | BOOST_STATIC_CONSTEXPR bool tinyness_before = false; |
563 | BOOST_STATIC_CONSTEXPR float_round_style round_style = round_to_nearest; |
564 | }; |
565 | |
566 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
567 | BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_specialized; |
568 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
569 | BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::digits; |
570 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
571 | BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::digits10; |
572 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
573 | BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_digits10; |
574 | |
575 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
576 | BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_signed; |
577 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
578 | BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_integer; |
579 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
580 | BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_exact; |
581 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
582 | BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::radix; |
583 | |
584 | |
585 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
586 | BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::min_exponent; |
587 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
588 | BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_exponent; |
589 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
590 | BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::min_exponent10; |
591 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
592 | BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_exponent10; |
593 | |
594 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
595 | BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_infinity; |
596 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
597 | BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_quiet_NaN; |
598 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
599 | BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_signaling_NaN; |
600 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
601 | BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_denorm_loss; |
602 | |
603 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
604 | BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_iec559; |
605 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
606 | BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_bounded; |
607 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
608 | BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_modulo; |
609 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
610 | BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::traps; |
611 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
612 | BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::tinyness_before; |
613 | |
614 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
615 | BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::round_style; |
616 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
617 | BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_denorm; |
618 | |
619 | } // namespace std |
620 | |
621 | |
622 | #endif |
623 | |