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
38extern "C" {
39#include <quadmath.h>
40}
41
42typedef __float128 float128_type;
43
44#elif defined(BOOST_MP_USE_QUAD)
45
46#include <boost/multiprecision/detail/float_string_cvt.hpp>
47
48typedef _Quad float128_type;
49
50extern "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
98inline _Quad isnanq(_Quad v)
99{
100 return v != v;
101}
102inline _Quad isinfq(_Quad v)
103{
104 return __fabsq(v) > 1.18973149535723176508575932662800702e4932Q;
105}
106
107#endif
108
109namespace boost{
110namespace multiprecision{
111namespace backends{
112
113struct float128_backend;
114
115}
116
117using backends::float128_backend;
118
119template<>
120struct number_category<backends::float128_backend> : public mpl::int_<number_kind_floating_point> {};
121template<>
122struct number_category<float128_type> : public mpl::int_<number_kind_floating_point> {};
123
124typedef number<float128_backend, et_off> float128;
125
126namespace backends{
127
128struct 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
136private:
137 float128_type m_value;
138public:
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
235inline void eval_add(float128_backend& result, const float128_backend& a)
236{
237 result.value() += a.value();
238}
239template <class A>
240inline void eval_add(float128_backend& result, const A& a)
241{
242 result.value() += a;
243}
244inline void eval_subtract(float128_backend& result, const float128_backend& a)
245{
246 result.value() -= a.value();
247}
248template <class A>
249inline void eval_subtract(float128_backend& result, const A& a)
250{
251 result.value() -= a;
252}
253inline void eval_multiply(float128_backend& result, const float128_backend& a)
254{
255 result.value() *= a.value();
256}
257template <class A>
258inline void eval_multiply(float128_backend& result, const A& a)
259{
260 result.value() *= a;
261}
262inline void eval_divide(float128_backend& result, const float128_backend& a)
263{
264 result.value() /= a.value();
265}
266template <class A>
267inline void eval_divide(float128_backend& result, const A& a)
268{
269 result.value() /= a;
270}
271
272inline void eval_add(float128_backend& result, const float128_backend& a, const float128_backend& b)
273{
274 result.value() = a.value() + b.value();
275}
276template <class A>
277inline void eval_add(float128_backend& result, const float128_backend& a, const A& b)
278{
279 result.value() = a.value() + b;
280}
281inline void eval_subtract(float128_backend& result, const float128_backend& a, const float128_backend& b)
282{
283 result.value() = a.value() - b.value();
284}
285template <class A>
286inline void eval_subtract(float128_backend& result, const float128_backend& a, const A& b)
287{
288 result.value() = a.value() - b;
289}
290template <class A>
291inline void eval_subtract(float128_backend& result, const A& a, const float128_backend& b)
292{
293 result.value() = a - b.value();
294}
295inline void eval_multiply(float128_backend& result, const float128_backend& a, const float128_backend& b)
296{
297 result.value() = a.value() * b.value();
298}
299template <class A>
300inline void eval_multiply(float128_backend& result, const float128_backend& a, const A& b)
301{
302 result.value() = a.value() * b;
303}
304inline void eval_divide(float128_backend& result, const float128_backend& a, const float128_backend& b)
305{
306 result.value() = a.value() / b.value();
307}
308
309template <class R>
310inline void eval_convert_to(R* result, const float128_backend& val)
311{
312 *result = static_cast<R>(val.value());
313}
314
315inline void eval_frexp(float128_backend& result, const float128_backend& arg, int* exp)
316{
317 result.value() = frexpq(arg.value(), exp);
318}
319
320inline void eval_ldexp(float128_backend& result, const float128_backend& arg, int exp)
321{
322 result.value() = ldexpq(arg.value(), exp);
323}
324
325inline void eval_floor(float128_backend& result, const float128_backend& arg)
326{
327 result.value() = floorq(arg.value());
328}
329inline void eval_ceil(float128_backend& result, const float128_backend& arg)
330{
331 result.value() = ceilq(arg.value());
332}
333inline void eval_sqrt(float128_backend& result, const float128_backend& arg)
334{
335 result.value() = sqrtq(arg.value());
336}
337inline 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
342inline void eval_increment(float128_backend& arg)
343{
344 ++arg.value();
345}
346inline void eval_decrement(float128_backend& arg)
347{
348 --arg.value();
349}
350
351/*********************************************************************
352*
353* abs/fabs:
354*
355*********************************************************************/
356
357inline void eval_abs(float128_backend& result, const float128_backend& arg)
358{
359 result.value() = fabsq(arg.value());
360}
361inline 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
372inline 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//
389inline 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
404inline void eval_exp(float128_backend& result, const float128_backend& arg)
405{
406 result.value() = expq(arg.value());
407}
408inline void eval_log(float128_backend& result, const float128_backend& arg)
409{
410 result.value() = logq(arg.value());
411}
412inline void eval_log10(float128_backend& result, const float128_backend& arg)
413{
414 result.value() = log10q(arg.value());
415}
416inline void eval_sin(float128_backend& result, const float128_backend& arg)
417{
418 result.value() = sinq(arg.value());
419}
420inline void eval_cos(float128_backend& result, const float128_backend& arg)
421{
422 result.value() = cosq(arg.value());
423}
424inline void eval_tan(float128_backend& result, const float128_backend& arg)
425{
426 result.value() = tanq(arg.value());
427}
428inline void eval_asin(float128_backend& result, const float128_backend& arg)
429{
430 result.value() = asinq(arg.value());
431}
432inline void eval_acos(float128_backend& result, const float128_backend& arg)
433{
434 result.value() = acosq(arg.value());
435}
436inline void eval_atan(float128_backend& result, const float128_backend& arg)
437{
438 result.value() = atanq(arg.value());
439}
440inline void eval_sinh(float128_backend& result, const float128_backend& arg)
441{
442 result.value() = sinhq(arg.value());
443}
444inline void eval_cosh(float128_backend& result, const float128_backend& arg)
445{
446 result.value() = coshq(arg.value());
447}
448inline void eval_tanh(float128_backend& result, const float128_backend& arg)
449{
450 result.value() = tanhq(arg.value());
451}
452inline void eval_fmod(float128_backend& result, const float128_backend& a, const float128_backend& b)
453{
454 result.value() = fmodq(a.value(), b.value());
455}
456inline void eval_pow(float128_backend& result, const float128_backend& a, const float128_backend& b)
457{
458 result.value() = powq(a.value(), b.value());
459}
460inline 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
469namespace boost{
470namespace archive{
471
472class binary_oarchive;
473class binary_iarchive;
474
475}
476
477namespace serialization{ namespace float128_detail{
478
479template <class Archive>
480void 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}
487template <class Archive>
488void 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
497template <class Archive>
498void 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}
504template <class Archive>
505void 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
514template <class Archive>
515void 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
525namespace std{
526
527template <boost::multiprecision::expression_template_option ExpressionTemplates>
528class 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;
531public:
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
566template <boost::multiprecision::expression_template_option ExpressionTemplates>
567BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_specialized;
568template <boost::multiprecision::expression_template_option ExpressionTemplates>
569BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::digits;
570template <boost::multiprecision::expression_template_option ExpressionTemplates>
571BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::digits10;
572template <boost::multiprecision::expression_template_option ExpressionTemplates>
573BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_digits10;
574
575template <boost::multiprecision::expression_template_option ExpressionTemplates>
576BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_signed;
577template <boost::multiprecision::expression_template_option ExpressionTemplates>
578BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_integer;
579template <boost::multiprecision::expression_template_option ExpressionTemplates>
580BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_exact;
581template <boost::multiprecision::expression_template_option ExpressionTemplates>
582BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::radix;
583
584
585template <boost::multiprecision::expression_template_option ExpressionTemplates>
586BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::min_exponent;
587template <boost::multiprecision::expression_template_option ExpressionTemplates>
588BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_exponent;
589template <boost::multiprecision::expression_template_option ExpressionTemplates>
590BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::min_exponent10;
591template <boost::multiprecision::expression_template_option ExpressionTemplates>
592BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_exponent10;
593
594template <boost::multiprecision::expression_template_option ExpressionTemplates>
595BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_infinity;
596template <boost::multiprecision::expression_template_option ExpressionTemplates>
597BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_quiet_NaN;
598template <boost::multiprecision::expression_template_option ExpressionTemplates>
599BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_signaling_NaN;
600template <boost::multiprecision::expression_template_option ExpressionTemplates>
601BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_denorm_loss;
602
603template <boost::multiprecision::expression_template_option ExpressionTemplates>
604BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_iec559;
605template <boost::multiprecision::expression_template_option ExpressionTemplates>
606BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_bounded;
607template <boost::multiprecision::expression_template_option ExpressionTemplates>
608BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_modulo;
609template <boost::multiprecision::expression_template_option ExpressionTemplates>
610BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::traps;
611template <boost::multiprecision::expression_template_option ExpressionTemplates>
612BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::tinyness_before;
613
614template <boost::multiprecision::expression_template_option ExpressionTemplates>
615BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::round_style;
616template <boost::multiprecision::expression_template_option ExpressionTemplates>
617BOOST_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

source code of boost/boost/multiprecision/float128.hpp