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 https://www.boost.org/LICENSE_1_0.txt
6 #ifndef BOOST_MP_FLOAT128_HPP
7 #define BOOST_MP_FLOAT128_HPP
9 #include <boost/config.hpp>
10 #include <boost/scoped_array.hpp>
11 #include <boost/functional/hash.hpp>
12 #include <boost/multiprecision/number.hpp>
14 #if defined(BOOST_INTEL) && !defined(BOOST_MP_USE_FLOAT128) && !defined(BOOST_MP_USE_QUAD)
15 #if defined(BOOST_INTEL_CXX_VERSION) && (BOOST_INTEL_CXX_VERSION >= 1310) && defined(__GNUC__)
16 #if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6))
17 #define BOOST_MP_USE_FLOAT128
21 #ifndef BOOST_MP_USE_FLOAT128
22 #define BOOST_MP_USE_QUAD
26 #if defined(__GNUC__) && !defined(BOOST_MP_USE_FLOAT128) && !defined(BOOST_MP_USE_QUAD)
27 #define BOOST_MP_USE_FLOAT128
30 #if !defined(BOOST_MP_USE_FLOAT128) && !defined(BOOST_MP_USE_QUAD)
31 #error "Sorry compiler is neither GCC, not Intel, don't know how to configure this header."
33 #if defined(BOOST_MP_USE_FLOAT128) && defined(BOOST_MP_USE_QUAD)
34 #error "Oh dear, both BOOST_MP_USE_FLOAT128 and BOOST_MP_USE_QUAD are defined, which one should I be using?"
37 #if defined(BOOST_MP_USE_FLOAT128)
43 typedef __float128 float128_type;
45 #elif defined(BOOST_MP_USE_QUAD)
47 #include <boost/multiprecision/detail/float_string_cvt.hpp>
49 typedef _Quad float128_type;
52 _Quad __ldexpq(_Quad, int);
53 _Quad __frexpq(_Quad, int*);
55 _Quad __floorq(_Quad);
58 _Quad __truncq(_Quad);
60 _Quad __powq(_Quad, _Quad);
62 _Quad __log10q(_Quad);
72 _Quad __fmodq(_Quad, _Quad);
73 _Quad __atan2q(_Quad, _Quad);
75 #define ldexpq __ldexpq
76 #define frexpq __frexpq
78 #define floorq __floorq
81 #define truncq __truncq
85 #define log10q __log10q
96 #define atan2q __atan2q
99 inline _Quad isnanq(_Quad v)
103 inline _Quad isinfq(_Quad v)
105 return __fabsq(v) > 1.18973149535723176508575932662800702e4932Q;
111 namespace multiprecision {
114 struct float128_backend;
118 using backends::float128_backend;
121 struct number_category<backends::float128_backend> : public mpl::int_<number_kind_floating_point>
123 #if defined(BOOST_MP_USE_QUAD)
125 struct number_category<float128_type> : public mpl::int_<number_kind_floating_point>
129 typedef number<float128_backend, et_off> float128;
131 #ifndef BOOST_NO_CXX11_CONSTEXPR
133 namespace quad_constants {
134 constexpr __float128 quad_min = static_cast<__float128>(1) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) / 1073741824;
136 constexpr __float128 quad_denorm_min = static_cast<__float128>(1) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) * static_cast<__float128>(DBL_MIN) / 5.5751862996326557854e+42;
138 constexpr double dbl_mult = 8.9884656743115795386e+307; // This has one bit set only.
139 constexpr __float128 quad_max = (static_cast<__float128>(1) - 9.62964972193617926527988971292463659e-35) // This now has all bits sets to 1
140 * static_cast<__float128>(dbl_mult) * static_cast<__float128>(dbl_mult) * static_cast<__float128>(dbl_mult) * static_cast<__float128>(dbl_mult) * static_cast<__float128>(dbl_mult) * static_cast<__float128>(dbl_mult) * static_cast<__float128>(dbl_mult) * static_cast<__float128>(dbl_mult) * static_cast<__float128>(dbl_mult) * static_cast<__float128>(dbl_mult) * static_cast<__float128>(dbl_mult) * static_cast<__float128>(dbl_mult) * static_cast<__float128>(dbl_mult) * static_cast<__float128>(dbl_mult) * static_cast<__float128>(dbl_mult) * static_cast<__float128>(dbl_mult) * 65536;
141 } // namespace quad_constants
143 #define BOOST_MP_QUAD_MIN boost::multiprecision::quad_constants::quad_min
144 #define BOOST_MP_QUAD_DENORM_MIN boost::multiprecision::quad_constants::quad_denorm_min
145 #define BOOST_MP_QUAD_MAX boost::multiprecision::quad_constants::quad_max
149 #define BOOST_MP_QUAD_MIN 3.36210314311209350626267781732175260e-4932Q
150 #define BOOST_MP_QUAD_DENORM_MIN 6.475175119438025110924438958227646552e-4966Q
151 #define BOOST_MP_QUAD_MAX 1.18973149535723176508575932662800702e4932Q
157 struct float128_backend
159 typedef mpl::list<signed char, short, int, long, boost::long_long_type> signed_types;
160 typedef mpl::list<unsigned char, unsigned short,
161 unsigned int, unsigned long, boost::ulong_long_type>
163 typedef mpl::list<float, double, long double> float_types;
164 typedef int exponent_type;
167 float128_type m_value;
170 BOOST_CONSTEXPR float128_backend() BOOST_NOEXCEPT : m_value(0) {}
171 BOOST_CONSTEXPR float128_backend(const float128_backend& o) BOOST_NOEXCEPT : m_value(o.m_value) {}
172 BOOST_MP_CXX14_CONSTEXPR float128_backend& operator=(const float128_backend& o) BOOST_NOEXCEPT
178 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&>()))
181 BOOST_MP_CXX14_CONSTEXPR 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&>()))
186 BOOST_MP_CXX14_CONSTEXPR float128_backend(long double const& f) : m_value(f)
188 if (::fabsl(f) > LDBL_MAX)
189 m_value = (f < 0) ? -static_cast<__float128>(HUGE_VAL) : static_cast<__float128>(HUGE_VAL);
191 BOOST_MP_CXX14_CONSTEXPR float128_backend& operator=(long double const& f)
194 m_value = static_cast<__float128>(HUGE_VAL);
195 else if (-f > LDBL_MAX)
196 m_value = -static_cast<__float128>(HUGE_VAL);
201 float128_backend& operator=(const char* s)
203 #ifndef BOOST_MP_USE_QUAD
205 m_value = strtoflt128(s, &p_end);
206 if (p_end - s != (std::ptrdiff_t)std::strlen(s))
208 BOOST_THROW_EXCEPTION(std::runtime_error("Unable to interpret input string as a floating point value"));
211 boost::multiprecision::detail::convert_from_string(*this, s);
215 BOOST_MP_CXX14_CONSTEXPR void swap(float128_backend& o) BOOST_NOEXCEPT
217 // We don't call std::swap here because it's no constexpr (yet):
218 float128_type t(o.value());
222 std::string str(std::streamsize digits, std::ios_base::fmtflags f) const
224 #ifndef BOOST_MP_USE_QUAD
226 std::string format = "%";
227 if (f & std::ios_base::showpos)
229 if (f & std::ios_base::showpoint)
236 if (f & std::ios_base::scientific)
238 else if (f & std::ios_base::fixed)
244 if ((f & std::ios_base::scientific) && (f & std::ios_base::fixed))
246 v = quadmath_snprintf(buf, sizeof buf, "%Qa", m_value);
250 v = quadmath_snprintf(buf, sizeof buf, format.c_str(), digits, m_value);
253 if ((v < 0) || (v >= 127))
256 boost::scoped_array<char> buf2;
257 buf2.reset(new char[v + 3]);
258 v = quadmath_snprintf(&buf2[0], v_max + 3, format.c_str(), digits, m_value);
261 BOOST_THROW_EXCEPTION(std::runtime_error("Formatting of float128_type failed."));
267 return boost::multiprecision::detail::convert_to_string(*this, digits ? digits : 37, f);
270 BOOST_MP_CXX14_CONSTEXPR void negate() BOOST_NOEXCEPT
274 BOOST_MP_CXX14_CONSTEXPR int compare(const float128_backend& o) const
276 return m_value == o.m_value ? 0 : m_value < o.m_value ? -1 : 1;
279 BOOST_MP_CXX14_CONSTEXPR int compare(const T& i) const
281 return m_value == i ? 0 : m_value < i ? -1 : 1;
283 BOOST_MP_CXX14_CONSTEXPR float128_type& value()
287 BOOST_MP_CXX14_CONSTEXPR const float128_type& value() const
293 inline BOOST_MP_CXX14_CONSTEXPR void eval_add(float128_backend& result, const float128_backend& a)
295 result.value() += a.value();
298 inline BOOST_MP_CXX14_CONSTEXPR void eval_add(float128_backend& result, const A& a)
302 inline BOOST_MP_CXX14_CONSTEXPR void eval_subtract(float128_backend& result, const float128_backend& a)
304 result.value() -= a.value();
307 inline BOOST_MP_CXX14_CONSTEXPR void eval_subtract(float128_backend& result, const A& a)
311 inline BOOST_MP_CXX14_CONSTEXPR void eval_multiply(float128_backend& result, const float128_backend& a)
313 result.value() *= a.value();
316 inline BOOST_MP_CXX14_CONSTEXPR void eval_multiply(float128_backend& result, const A& a)
320 inline BOOST_MP_CXX14_CONSTEXPR void eval_divide(float128_backend& result, const float128_backend& a)
322 result.value() /= a.value();
325 inline BOOST_MP_CXX14_CONSTEXPR void eval_divide(float128_backend& result, const A& a)
330 inline BOOST_MP_CXX14_CONSTEXPR void eval_add(float128_backend& result, const float128_backend& a, const float128_backend& b)
332 result.value() = a.value() + b.value();
335 inline BOOST_MP_CXX14_CONSTEXPR void eval_add(float128_backend& result, const float128_backend& a, const A& b)
337 result.value() = a.value() + b;
339 inline BOOST_MP_CXX14_CONSTEXPR void eval_subtract(float128_backend& result, const float128_backend& a, const float128_backend& b)
341 result.value() = a.value() - b.value();
344 inline BOOST_MP_CXX14_CONSTEXPR void eval_subtract(float128_backend& result, const float128_backend& a, const A& b)
346 result.value() = a.value() - b;
349 inline BOOST_MP_CXX14_CONSTEXPR void eval_subtract(float128_backend& result, const A& a, const float128_backend& b)
351 result.value() = a - b.value();
353 inline BOOST_MP_CXX14_CONSTEXPR void eval_multiply(float128_backend& result, const float128_backend& a, const float128_backend& b)
355 result.value() = a.value() * b.value();
358 inline BOOST_MP_CXX14_CONSTEXPR void eval_multiply(float128_backend& result, const float128_backend& a, const A& b)
360 result.value() = a.value() * b;
362 inline BOOST_MP_CXX14_CONSTEXPR void eval_divide(float128_backend& result, const float128_backend& a, const float128_backend& b)
364 result.value() = a.value() / b.value();
368 inline BOOST_MP_CXX14_CONSTEXPR void eval_convert_to(R* result, const float128_backend& val)
370 *result = static_cast<R>(val.value());
373 inline void eval_frexp(float128_backend& result, const float128_backend& arg, int* exp)
375 result.value() = frexpq(arg.value(), exp);
378 inline void eval_ldexp(float128_backend& result, const float128_backend& arg, int exp)
380 result.value() = ldexpq(arg.value(), exp);
383 inline void eval_floor(float128_backend& result, const float128_backend& arg)
385 result.value() = floorq(arg.value());
387 inline void eval_ceil(float128_backend& result, const float128_backend& arg)
389 result.value() = ceilq(arg.value());
391 inline void eval_sqrt(float128_backend& result, const float128_backend& arg)
393 result.value() = sqrtq(arg.value());
395 #ifndef BOOST_MP_NO_CONSTEXPR_DETECTION
396 inline BOOST_MP_CXX14_CONSTEXPR
400 int eval_fpclassify(const float128_backend& arg)
402 float128_type v = arg.value();
403 #ifndef BOOST_MP_NO_CONSTEXPR_DETECTION
404 if (BOOST_MP_IS_CONST_EVALUATED(v))
413 if (t > BOOST_MP_QUAD_MAX)
415 if (t < BOOST_MP_QUAD_MIN)
429 float128_backend t(arg);
432 if (t.value() < BOOST_MP_QUAD_MIN)
437 #if defined(BOOST_GCC) && (__GNUC__ == 9)
438 // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91705
439 inline BOOST_MP_CXX14_CONSTEXPR void eval_increment(float128_backend& arg)
441 arg.value() = 1 + arg.value();
443 inline BOOST_MP_CXX14_CONSTEXPR void eval_decrement(float128_backend& arg)
445 arg.value() = arg.value() - 1;
448 inline BOOST_MP_CXX14_CONSTEXPR void eval_increment(float128_backend& arg)
452 inline BOOST_MP_CXX14_CONSTEXPR void eval_decrement(float128_backend& arg)
458 /*********************************************************************
462 *********************************************************************/
464 #ifndef BOOST_MP_NO_CONSTEXPR_DETECTION
465 inline BOOST_MP_CXX14_CONSTEXPR void eval_abs(float128_backend& result, const float128_backend& arg)
467 inline void eval_abs(float128_backend& result, const float128_backend& arg)
470 float128_type v(arg.value());
471 #ifndef BOOST_MP_NO_CONSTEXPR_DETECTION
472 if (BOOST_MP_IS_CONST_EVALUATED(v))
474 result.value() = v < 0 ? -v : v;
479 result.value() = fabsq(arg.value());
482 #ifndef BOOST_MP_NO_CONSTEXPR_DETECTION
483 inline BOOST_MP_CXX14_CONSTEXPR void eval_fabs(float128_backend& result, const float128_backend& arg)
485 inline void eval_fabs(float128_backend& result, const float128_backend& arg)
488 float128_type v(arg.value());
489 #ifndef BOOST_MP_NO_CONSTEXPR_DETECTION
490 if (BOOST_MP_IS_CONST_EVALUATED(v))
492 result.value() = v < 0 ? -v : v;
497 result.value() = fabsq(arg.value());
501 /*********************************************************************
503 * Floating point functions:
505 *********************************************************************/
507 inline void eval_trunc(float128_backend& result, const float128_backend& arg)
509 result.value() = truncq(arg.value());
513 // This doesn't actually work... rely on our own default version instead.
515 inline void eval_round(float128_backend& result, const float128_backend& arg)
517 if(isnanq(arg.value()) || isinf(arg.value()))
519 result = boost::math::policies::raise_rounding_error(
520 "boost::multiprecision::trunc<%1%>(%1%)", 0,
521 number<float128_backend, et_off>(arg),
522 number<float128_backend, et_off>(arg),
523 boost::math::policies::policy<>()).backend();
526 result.value() = roundq(arg.value());
530 inline void eval_exp(float128_backend& result, const float128_backend& arg)
532 result.value() = expq(arg.value());
534 inline void eval_log(float128_backend& result, const float128_backend& arg)
536 result.value() = logq(arg.value());
538 inline void eval_log10(float128_backend& result, const float128_backend& arg)
540 result.value() = log10q(arg.value());
542 inline void eval_sin(float128_backend& result, const float128_backend& arg)
544 result.value() = sinq(arg.value());
546 inline void eval_cos(float128_backend& result, const float128_backend& arg)
548 result.value() = cosq(arg.value());
550 inline void eval_tan(float128_backend& result, const float128_backend& arg)
552 result.value() = tanq(arg.value());
554 inline void eval_asin(float128_backend& result, const float128_backend& arg)
556 result.value() = asinq(arg.value());
558 inline void eval_acos(float128_backend& result, const float128_backend& arg)
560 result.value() = acosq(arg.value());
562 inline void eval_atan(float128_backend& result, const float128_backend& arg)
564 result.value() = atanq(arg.value());
566 inline void eval_sinh(float128_backend& result, const float128_backend& arg)
568 result.value() = sinhq(arg.value());
570 inline void eval_cosh(float128_backend& result, const float128_backend& arg)
572 result.value() = coshq(arg.value());
574 inline void eval_tanh(float128_backend& result, const float128_backend& arg)
576 result.value() = tanhq(arg.value());
578 inline void eval_fmod(float128_backend& result, const float128_backend& a, const float128_backend& b)
580 result.value() = fmodq(a.value(), b.value());
582 inline void eval_pow(float128_backend& result, const float128_backend& a, const float128_backend& b)
584 result.value() = powq(a.value(), b.value());
586 inline void eval_atan2(float128_backend& result, const float128_backend& a, const float128_backend& b)
588 result.value() = atan2q(a.value(), b.value());
590 #ifndef BOOST_MP_USE_QUAD
591 inline void eval_multiply_add(float128_backend& result, const float128_backend& a, const float128_backend& b, const float128_backend& c)
593 result.value() = fmaq(a.value(), b.value(), c.value());
595 inline int eval_signbit BOOST_PREVENT_MACRO_SUBSTITUTION(const float128_backend& arg)
597 return ::signbitq(arg.value());
601 inline std::size_t hash_value(const float128_backend& val)
603 return boost::hash_value(static_cast<double>(val.value()));
606 } // namespace backends
608 template <boost::multiprecision::expression_template_option ExpressionTemplates>
609 inline boost::multiprecision::number<float128_backend, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg)
611 return asinhq(arg.backend().value());
613 template <boost::multiprecision::expression_template_option ExpressionTemplates>
614 inline boost::multiprecision::number<float128_backend, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg)
616 return acoshq(arg.backend().value());
618 template <boost::multiprecision::expression_template_option ExpressionTemplates>
619 inline boost::multiprecision::number<float128_backend, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg)
621 return atanhq(arg.backend().value());
623 template <boost::multiprecision::expression_template_option ExpressionTemplates>
624 inline boost::multiprecision::number<float128_backend, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg)
626 return cbrtq(arg.backend().value());
628 template <boost::multiprecision::expression_template_option ExpressionTemplates>
629 inline boost::multiprecision::number<float128_backend, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg)
631 return erfq(arg.backend().value());
633 template <boost::multiprecision::expression_template_option ExpressionTemplates>
634 inline boost::multiprecision::number<float128_backend, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg)
636 return erfcq(arg.backend().value());
638 template <boost::multiprecision::expression_template_option ExpressionTemplates>
639 inline boost::multiprecision::number<float128_backend, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg)
641 return expm1q(arg.backend().value());
643 template <boost::multiprecision::expression_template_option ExpressionTemplates>
644 inline boost::multiprecision::number<float128_backend, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg)
646 return lgammaq(arg.backend().value());
648 template <boost::multiprecision::expression_template_option ExpressionTemplates>
649 inline boost::multiprecision::number<float128_backend, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg)
651 return tgammaq(arg.backend().value());
653 template <boost::multiprecision::expression_template_option ExpressionTemplates>
654 inline boost::multiprecision::number<float128_backend, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg)
656 return log1pq(arg.backend().value());
659 #ifndef BOOST_MP_USE_QUAD
660 template <multiprecision::expression_template_option ExpressionTemplates>
661 inline boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> copysign BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates>& a, const boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates>& b)
663 return ::copysignq(a.backend().value(), b.backend().value());
666 inline void eval_remainder(float128_backend& result, const float128_backend& a, const float128_backend& b)
668 result.value() = remainderq(a.value(), b.value());
670 inline void eval_remainder(float128_backend& result, const float128_backend& a, const float128_backend& b, int* pi)
672 result.value() = remquoq(a.value(), b.value(), pi);
676 } // namespace multiprecision
680 using boost::multiprecision::copysign;
681 using boost::multiprecision::signbit;
690 class binary_oarchive;
691 class binary_iarchive;
693 } // namespace archive
695 namespace serialization {
696 namespace float128_detail {
698 template <class Archive>
699 void do_serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, const mpl::false_&, const mpl::false_&)
703 std::string s(val.str(0, std::ios_base::scientific));
704 ar& boost::make_nvp("value", s);
706 template <class Archive>
707 void do_serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, const mpl::true_&, const mpl::false_&)
712 ar& boost::make_nvp("value", s);
716 template <class Archive>
717 void do_serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, const mpl::false_&, const mpl::true_&)
721 ar.save_binary(&val, sizeof(val));
723 template <class Archive>
724 void do_serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, const mpl::true_&, const mpl::true_&)
728 ar.load_binary(&val, sizeof(val));
731 } // namespace float128_detail
733 template <class Archive>
734 void serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, unsigned int /*version*/)
736 typedef typename Archive::is_loading load_tag;
737 typedef typename mpl::bool_<boost::is_same<Archive, boost::archive::binary_oarchive>::value || boost::is_same<Archive, boost::archive::binary_iarchive>::value> binary_tag;
739 float128_detail::do_serialize(ar, val, load_tag(), binary_tag());
742 } // namespace serialization
748 template <boost::multiprecision::expression_template_option ExpressionTemplates>
749 class numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >
751 typedef boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> number_type;
754 BOOST_STATIC_CONSTEXPR bool is_specialized = true;
755 static BOOST_MP_CXX14_CONSTEXPR number_type(min)() BOOST_NOEXCEPT { return BOOST_MP_QUAD_MIN; }
756 static BOOST_MP_CXX14_CONSTEXPR number_type(max)() BOOST_NOEXCEPT { return BOOST_MP_QUAD_MAX; }
757 static BOOST_MP_CXX14_CONSTEXPR number_type lowest() BOOST_NOEXCEPT { return -(max)(); }
758 BOOST_STATIC_CONSTEXPR int digits = 113;
759 BOOST_STATIC_CONSTEXPR int digits10 = 33;
760 BOOST_STATIC_CONSTEXPR int max_digits10 = 36;
761 BOOST_STATIC_CONSTEXPR bool is_signed = true;
762 BOOST_STATIC_CONSTEXPR bool is_integer = false;
763 BOOST_STATIC_CONSTEXPR bool is_exact = false;
764 BOOST_STATIC_CONSTEXPR int radix = 2;
765 static BOOST_MP_CXX14_CONSTEXPR number_type epsilon() { return 1.92592994438723585305597794258492732e-34; /* this double value has only one bit set and so is exact */ }
766 static BOOST_MP_CXX14_CONSTEXPR number_type round_error() { return 0.5; }
767 BOOST_STATIC_CONSTEXPR int min_exponent = -16381;
768 BOOST_STATIC_CONSTEXPR int min_exponent10 = min_exponent * 301L / 1000L;
769 BOOST_STATIC_CONSTEXPR int max_exponent = 16384;
770 BOOST_STATIC_CONSTEXPR int max_exponent10 = max_exponent * 301L / 1000L;
771 BOOST_STATIC_CONSTEXPR bool has_infinity = true;
772 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = true;
773 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
774 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_present;
775 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = true;
776 static BOOST_MP_CXX14_CONSTEXPR number_type infinity() { return HUGE_VAL; /* conversion from double infinity OK */ }
777 static BOOST_MP_CXX14_CONSTEXPR number_type quiet_NaN() { return number_type("nan"); }
778 static BOOST_MP_CXX14_CONSTEXPR number_type signaling_NaN() { return 0; }
779 static BOOST_MP_CXX14_CONSTEXPR number_type denorm_min() { return BOOST_MP_QUAD_DENORM_MIN; }
780 BOOST_STATIC_CONSTEXPR bool is_iec559 = true;
781 BOOST_STATIC_CONSTEXPR bool is_bounded = true;
782 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
783 BOOST_STATIC_CONSTEXPR bool traps = false;
784 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
785 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_to_nearest;
788 template <boost::multiprecision::expression_template_option ExpressionTemplates>
789 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_specialized;
790 template <boost::multiprecision::expression_template_option ExpressionTemplates>
791 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::digits;
792 template <boost::multiprecision::expression_template_option ExpressionTemplates>
793 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::digits10;
794 template <boost::multiprecision::expression_template_option ExpressionTemplates>
795 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_digits10;
797 template <boost::multiprecision::expression_template_option ExpressionTemplates>
798 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_signed;
799 template <boost::multiprecision::expression_template_option ExpressionTemplates>
800 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_integer;
801 template <boost::multiprecision::expression_template_option ExpressionTemplates>
802 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_exact;
803 template <boost::multiprecision::expression_template_option ExpressionTemplates>
804 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::radix;
806 template <boost::multiprecision::expression_template_option ExpressionTemplates>
807 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::min_exponent;
808 template <boost::multiprecision::expression_template_option ExpressionTemplates>
809 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_exponent;
810 template <boost::multiprecision::expression_template_option ExpressionTemplates>
811 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::min_exponent10;
812 template <boost::multiprecision::expression_template_option ExpressionTemplates>
813 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_exponent10;
815 template <boost::multiprecision::expression_template_option ExpressionTemplates>
816 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_infinity;
817 template <boost::multiprecision::expression_template_option ExpressionTemplates>
818 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_quiet_NaN;
819 template <boost::multiprecision::expression_template_option ExpressionTemplates>
820 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_signaling_NaN;
821 template <boost::multiprecision::expression_template_option ExpressionTemplates>
822 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_denorm_loss;
824 template <boost::multiprecision::expression_template_option ExpressionTemplates>
825 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_iec559;
826 template <boost::multiprecision::expression_template_option ExpressionTemplates>
827 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_bounded;
828 template <boost::multiprecision::expression_template_option ExpressionTemplates>
829 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_modulo;
830 template <boost::multiprecision::expression_template_option ExpressionTemplates>
831 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::traps;
832 template <boost::multiprecision::expression_template_option ExpressionTemplates>
833 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::tinyness_before;
835 template <boost::multiprecision::expression_template_option ExpressionTemplates>
836 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::round_style;
837 template <boost::multiprecision::expression_template_option ExpressionTemplates>
838 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_denorm;