Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:48:39

0001 ////////////////////////////////////////////////////////////////
0002 //  Copyright 2013 - 2022 John Maddock.
0003 //  Copyright 2022 Christopher Kormanyos.
0004 //  Distributed under the Boost Software License,
0005 //  Version 1.0. (See accompanying file LICENSE_1_0.txt
0006 //  or copy at https://www.boost.org/LICENSE_1_0.txt)
0007 
0008 #ifndef BOOST_MP_CPP_BIN_FLOAT_HPP
0009 #define BOOST_MP_CPP_BIN_FLOAT_HPP
0010 
0011 #include <cmath>
0012 #include <cstdint>
0013 #include <limits>
0014 #include <type_traits>
0015 #include <boost/multiprecision/cpp_int.hpp>
0016 #include <boost/multiprecision/integer.hpp>
0017 #include <boost/multiprecision/detail/standalone_config.hpp>
0018 #include <boost/multiprecision/detail/fpclassify.hpp>
0019 #include <boost/multiprecision/detail/float_string_cvt.hpp>
0020 #include <boost/multiprecision/traits/max_digits10.hpp>
0021 #include <boost/multiprecision/detail/hash.hpp>
0022 #include <boost/multiprecision/detail/no_exceptions_support.hpp>
0023 #include <boost/multiprecision/detail/assert.hpp>
0024 #include <boost/multiprecision/detail/float128_functions.hpp>
0025 #include <boost/multiprecision/detail/functions/trunc.hpp>
0026 
0027 //
0028 // Some includes we need from Boost.Math, since we rely on that library to provide these functions:
0029 //
0030 #ifdef BOOST_MP_MATH_AVAILABLE
0031 #include <boost/math/special_functions/asinh.hpp>
0032 #include <boost/math/special_functions/acosh.hpp>
0033 #include <boost/math/special_functions/atanh.hpp>
0034 #include <boost/math/special_functions/cbrt.hpp>
0035 #include <boost/math/special_functions/expm1.hpp>
0036 #include <boost/math/special_functions/gamma.hpp>
0037 #endif
0038 
0039 #ifdef BOOST_HAS_FLOAT128
0040 #include <quadmath.h>
0041 #endif
0042 
0043 namespace boost {
0044 namespace multiprecision {
0045 namespace backends {
0046 
0047 #ifdef BOOST_MSVC
0048 #pragma warning(push)
0049 #pragma warning(disable : 4522 6326) // multiple assignment operators specified, comparison of two constants
0050 #endif
0051 
0052 namespace detail {
0053 
0054 template <class U>
0055 inline typename std::enable_if<boost::multiprecision::detail::is_unsigned<U>::value, bool>::type is_negative(U) { return false; }
0056 template <class S>
0057 inline typename std::enable_if< !boost::multiprecision::detail::is_unsigned<S>::value, bool>::type is_negative(S s) { return s < 0; }
0058 
0059 template <class Float, std::ptrdiff_t, bool = number_category<Float>::value == number_kind_floating_point>
0060 struct is_cpp_bin_float_implicitly_constructible_from_type
0061 {
0062    static constexpr bool value = false;
0063 };
0064 
0065 template <class Float, std::ptrdiff_t bit_count>
0066 struct is_cpp_bin_float_implicitly_constructible_from_type<Float, bit_count, true>
0067 {
0068    static constexpr bool value = (std::numeric_limits<Float>::digits <= static_cast<int>(bit_count)) && (std::numeric_limits<Float>::radix == 2) && std::numeric_limits<Float>::is_specialized
0069 #ifdef BOOST_HAS_FLOAT128
0070                              && !std::is_same<Float, float128_type>::value
0071 #endif
0072                              && (std::is_floating_point<Float>::value || is_number<Float>::value);
0073 };
0074 
0075 template <class Float, std::ptrdiff_t, bool = number_category<Float>::value == number_kind_floating_point>
0076 struct is_cpp_bin_float_explicitly_constructible_from_type
0077 {
0078    static constexpr bool value = false;
0079 };
0080 
0081 template <class Float, std::ptrdiff_t bit_count>
0082 struct is_cpp_bin_float_explicitly_constructible_from_type<Float, bit_count, true>
0083 {
0084    static constexpr bool value = (std::numeric_limits<Float>::digits > static_cast<int>(bit_count)) && (std::numeric_limits<Float>::radix == 2) && std::numeric_limits<Float>::is_specialized
0085 #ifdef BOOST_HAS_FLOAT128
0086                              && !std::is_same<Float, float128_type>::value
0087 #endif
0088        ;
0089 };
0090 
0091 } // namespace detail
0092 
0093 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinExponent, Exponent MaxExponent>
0094 class cpp_bin_float
0095 {
0096  public:
0097    static constexpr unsigned bit_count = DigitBase == digit_base_2 ? Digits : (Digits * 1000uL) / 301uL + (((Digits * 1000uL) % 301) ? 2u : 1u);
0098    using rep_type = cpp_int_backend<std::is_void<Allocator>::value ? bit_count : 0, bit_count, std::is_void<Allocator>::value ? unsigned_magnitude : signed_magnitude, unchecked, Allocator>;
0099    using double_rep_type = cpp_int_backend<std::is_void<Allocator>::value ? 2 * bit_count : 0, 2 * bit_count, std::is_void<Allocator>::value ? unsigned_magnitude : signed_magnitude, unchecked, Allocator>;
0100 
0101    using signed_types = typename rep_type::signed_types;
0102    using unsigned_types = typename rep_type::unsigned_types;
0103    using float_types = std::tuple<float, double, long double>;
0104    using exponent_type = Exponent;
0105 
0106    static constexpr exponent_type max_exponent_limit = (std::numeric_limits<exponent_type>::max)()- 2 * static_cast<exponent_type>(bit_count);
0107    static constexpr exponent_type min_exponent_limit = (std::numeric_limits<exponent_type>::min)() + 2 * static_cast<exponent_type>(bit_count);
0108 
0109    static_assert(MinExponent >= min_exponent_limit, "Template parameter MinExponent is too negative for our internal logic to function correctly, sorry!");
0110    static_assert(MaxExponent <= max_exponent_limit, "Template parameter MaxExponent is too large for our internal logic to function correctly, sorry!");
0111    static_assert(MinExponent <= 0, "Template parameter MinExponent can not be positive!");
0112    static_assert(MaxExponent >= 0, "Template parameter MaxExponent can not be negative!");
0113 
0114    static constexpr exponent_type max_exponent = MaxExponent == 0 ? max_exponent_limit : MaxExponent;
0115    static constexpr exponent_type min_exponent = MinExponent == 0 ? min_exponent_limit : MinExponent;
0116 
0117    static constexpr exponent_type exponent_zero     = max_exponent + 1;
0118    static constexpr exponent_type exponent_infinity = max_exponent + 2;
0119    static constexpr exponent_type exponent_nan      = max_exponent + 3;
0120 
0121  private:
0122    rep_type      m_data;
0123    exponent_type m_exponent;
0124    bool          m_sign;
0125 
0126  public:
0127    cpp_bin_float() noexcept(noexcept(rep_type())) : m_data(), m_exponent(exponent_zero), m_sign(false) {}
0128 
0129    cpp_bin_float(const cpp_bin_float& o) noexcept(noexcept(rep_type(std::declval<const rep_type&>())))
0130        : m_data(o.m_data), m_exponent(o.m_exponent), m_sign(o.m_sign) {}
0131 
0132    template <unsigned D, digit_base_type B, class A, class E, E MinE, E MaxE>
0133    cpp_bin_float(const cpp_bin_float<D, B, A, E, MinE, MaxE>& o, typename std::enable_if<(bit_count >= cpp_bin_float<D, B, A, E, MinE, MaxE>::bit_count)>::type const* = nullptr)
0134    {
0135       *this = o;
0136    }
0137    template <unsigned D, digit_base_type B, class A, class E, E MinE, E MaxE>
0138    explicit cpp_bin_float(const cpp_bin_float<D, B, A, E, MinE, MaxE>& o, typename std::enable_if< !(bit_count >= cpp_bin_float<D, B, A, E, MinE, MaxE>::bit_count)>::type const* = nullptr)
0139        : m_exponent(o.exponent()), m_sign(o.sign())
0140    {
0141       *this = o;
0142    }
0143    // rvalue copy:
0144    template <unsigned D, digit_base_type B, class A, class E, E MinE, E MaxE>
0145    cpp_bin_float(cpp_bin_float<D, B, A, E, MinE, MaxE>&& o, typename std::enable_if<(bit_count >= cpp_bin_float<D, B, A, E, MinE, MaxE>::bit_count)>::type const* = nullptr)noexcept(noexcept(rep_type(std::declval<rep_type&&>())))
0146    {
0147       *this = std::move(o);
0148    }
0149    template <unsigned D, digit_base_type B, class A, class E, E MinE, E MaxE>
0150    explicit cpp_bin_float(cpp_bin_float<D, B, A, E, MinE, MaxE>&& o, typename std::enable_if< !(bit_count >= cpp_bin_float<D, B, A, E, MinE, MaxE>::bit_count)>::type const* = nullptr) noexcept(noexcept(rep_type(std::declval<rep_type&&>())))
0151        : m_exponent(o.exponent()), m_sign(o.sign())
0152    {
0153       *this = std::move(o);
0154    }
0155    template <class Float>
0156    cpp_bin_float(const Float& f,
0157                  typename std::enable_if<detail::is_cpp_bin_float_implicitly_constructible_from_type<Float, static_cast<std::ptrdiff_t>(bit_count)>::value>::type const* = nullptr)
0158        : m_data(), m_exponent(0), m_sign(false)
0159    {
0160       this->assign_float(f);
0161    }
0162 
0163    template <class Float>
0164    explicit cpp_bin_float(const Float& f,
0165                           typename std::enable_if<detail::is_cpp_bin_float_explicitly_constructible_from_type<Float, static_cast<std::ptrdiff_t>(bit_count)>::value>::type const* = nullptr)
0166        : m_data(), m_exponent(0), m_sign(false)
0167    {
0168       this->assign_float(f);
0169    }
0170 #ifdef BOOST_HAS_FLOAT128
0171    template <class Float>
0172    cpp_bin_float(const Float& f,
0173                  typename std::enable_if<
0174                      std::is_same<Float, float128_type>::value && (static_cast<int>(bit_count) >= 113)>::type const* = nullptr)
0175        : m_data(), m_exponent(0), m_sign(false)
0176    {
0177       this->assign_float(f);
0178    }
0179    template <class Float>
0180    explicit cpp_bin_float(const Float& f,
0181                           typename std::enable_if<
0182                               std::is_same<Float, float128_type>::value && (static_cast<int>(bit_count) < 113)>::type const* = nullptr)
0183        : m_data(), m_exponent(0), m_sign(false)
0184    {
0185       this->assign_float(f);
0186    }
0187 #endif
0188    cpp_bin_float& operator=(const cpp_bin_float& o) noexcept(noexcept(std::declval<rep_type&>() = std::declval<const rep_type&>()))
0189    {
0190       m_data     = o.m_data;
0191       m_exponent = o.m_exponent;
0192       m_sign     = o.m_sign;
0193       return *this;
0194    }
0195 
0196    template <class A, class E, E MinE, E MaxE>
0197    cpp_bin_float& operator=(const cpp_bin_float<Digits, DigitBase, A, E, MinE, MaxE>& o) noexcept(noexcept(std::declval<rep_type&>() = std::declval<const rep_type&>()))
0198    {
0199       m_data     = o.bits();
0200       m_sign     = o.sign();
0201       if (o.exponent() == cpp_bin_float<Digits, DigitBase, A, E, MinE, MaxE>::exponent_zero)
0202          m_exponent = exponent_zero;
0203       else if (o.exponent() == cpp_bin_float<Digits, DigitBase, A, E, MinE, MaxE>::exponent_nan)
0204          m_exponent = exponent_nan;
0205       else if (o.exponent() == cpp_bin_float<Digits, DigitBase, A, E, MinE, MaxE>::exponent_infinity)
0206          m_exponent = exponent_infinity;
0207       else if (o.exponent() > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent)
0208       {
0209          // Overflow:
0210          exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
0211          bits() = static_cast<limb_type>(0u);
0212       }
0213       else if (o.exponent() < cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent)
0214       {
0215          // Underflow:
0216          exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
0217          bits() = static_cast<limb_type>(0u);
0218       }
0219       else
0220          m_exponent = o.exponent();
0221       return *this;
0222    }
0223    // rvalue copy:
0224    template <class A, class E, E MinE, E MaxE>
0225    cpp_bin_float& operator=(cpp_bin_float<Digits, DigitBase, A, E, MinE, MaxE>&& o) noexcept(noexcept(std::declval<rep_type&>() = std::declval<rep_type&&>()))
0226    {
0227       m_data     = std::move(o.bits());
0228       m_sign     = o.sign();
0229       if (o.exponent() == cpp_bin_float<Digits, DigitBase, A, E, MinE, MaxE>::exponent_zero)
0230          m_exponent = exponent_zero;
0231       else if (o.exponent() == cpp_bin_float<Digits, DigitBase, A, E, MinE, MaxE>::exponent_nan)
0232          m_exponent = exponent_nan;
0233       else if (o.exponent() == cpp_bin_float<Digits, DigitBase, A, E, MinE, MaxE>::exponent_infinity)
0234          m_exponent = exponent_infinity;
0235       else if (o.exponent() > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent)
0236       {
0237          // Overflow:
0238          exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
0239          bits() = static_cast<limb_type>(0u);
0240       }
0241       else if (o.exponent() < cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent)
0242       {
0243          // Underflow:
0244          exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
0245          bits() = static_cast<limb_type>(0u);
0246       }
0247       else
0248          m_exponent = o.exponent();
0249       return *this;
0250    }
0251    template <unsigned D, digit_base_type B, class A, class E, E MinE, E MaxE>
0252    cpp_bin_float& operator=(const cpp_bin_float<D, B, A, E, MinE, MaxE>& f)
0253    {
0254       switch (eval_fpclassify(f))
0255       {
0256       case FP_ZERO:
0257          m_data     = limb_type(0);
0258          m_sign     = f.sign();
0259          m_exponent = exponent_zero;
0260          break;
0261       case FP_NAN:
0262          m_data     = limb_type(0);
0263          m_sign     = false;
0264          m_exponent = exponent_nan;
0265          break;
0266          ;
0267       case FP_INFINITE:
0268          m_data     = limb_type(0);
0269          m_sign     = f.sign();
0270          m_exponent = exponent_infinity;
0271          break;
0272       default:
0273          typename cpp_bin_float<D, B, A, E, MinE, MaxE>::rep_type b(f.bits());
0274          this->exponent() = f.exponent() + (E)bit_count - (E)cpp_bin_float<D, B, A, E, MinE, MaxE>::bit_count;
0275          this->sign()     = f.sign();
0276          copy_and_round(*this, b);
0277       }
0278       return *this;
0279    }
0280 #ifdef BOOST_HAS_FLOAT128
0281    template <class Float>
0282    typename std::enable_if<
0283        (number_category<Float>::value == number_kind_floating_point)
0284            //&& (std::numeric_limits<Float>::digits <= static_cast<int>(bit_count))
0285            && ((std::numeric_limits<Float>::radix == 2) || (std::is_same<Float, float128_type>::value)),
0286        cpp_bin_float&>::type
0287    operator=(const Float& f)
0288 #else
0289    template <class Float>
0290    typename std::enable_if<
0291        (number_category<Float>::value == number_kind_floating_point)
0292            //&& (std::numeric_limits<Float>::digits <= static_cast<int>(bit_count))
0293            && (std::numeric_limits<Float>::radix == 2),
0294        cpp_bin_float&>::type
0295    operator=(const Float& f)
0296 #endif
0297    {
0298       return assign_float(f);
0299    }
0300 
0301 #ifdef BOOST_HAS_FLOAT128
0302    template <class Float>
0303    typename std::enable_if<std::is_same<Float, float128_type>::value, cpp_bin_float&>::type assign_float(Float f)
0304    {
0305       using default_ops::eval_add;
0306       using bf_int_type = typename boost::multiprecision::detail::canonical<int, cpp_bin_float>::type;
0307       if (f == 0)
0308       {
0309          m_data     = limb_type(0);
0310          m_sign     = (signbitq(f) > 0);
0311          m_exponent = exponent_zero;
0312          return *this;
0313       }
0314       else if (isnanq(f))
0315       {
0316          m_data     = limb_type(0);
0317          m_sign     = false;
0318          m_exponent = exponent_nan;
0319          return *this;
0320       }
0321       else if (isinfq(f))
0322       {
0323          m_data     = limb_type(0);
0324          m_sign     = (f < 0);
0325          m_exponent = exponent_infinity;
0326          return *this;
0327       }
0328       if (f < 0)
0329       {
0330          *this = -f;
0331          this->negate();
0332          return *this;
0333       }
0334 
0335       using ui_type = typename std::tuple_element<0, unsigned_types>::type;
0336       m_data     = static_cast<ui_type>(0u);
0337       m_sign     = false;
0338       m_exponent = 0;
0339 
0340       constexpr std::ptrdiff_t bits = sizeof(int) * CHAR_BIT - 1;
0341       int              e;
0342       f = frexpq(f, &e);
0343       while (f)
0344       {
0345          f = ldexpq(f, bits);
0346          e -= bits;
0347          int ipart = static_cast<int>(truncq(f));
0348          f -= ipart;
0349          m_exponent += bits;
0350          cpp_bin_float t;
0351          t = static_cast<bf_int_type>(ipart);
0352          eval_add(*this, t);
0353       }
0354       m_exponent += static_cast<Exponent>(e);
0355       return *this;
0356    }
0357 #endif
0358 #ifdef BOOST_HAS_FLOAT128
0359    template <class Float>
0360    typename std::enable_if<std::is_floating_point<Float>::value && !std::is_same<Float, float128_type>::value, cpp_bin_float&>::type assign_float(Float f)
0361 #else
0362    template <class Float>
0363    typename std::enable_if<std::is_floating_point<Float>::value, cpp_bin_float&>::type assign_float(Float f)
0364 #endif
0365    {
0366       using std::frexp;
0367       using std::ldexp;
0368       using std::signbit;
0369       using default_ops::eval_add;
0370       using bf_int_type = typename boost::multiprecision::detail::canonical<int, cpp_bin_float>::type;
0371 
0372       switch (BOOST_MP_FPCLASSIFY(f))
0373       {
0374       case FP_ZERO:
0375          m_data     = limb_type(0);
0376          m_sign     = ((signbit)(f));
0377          m_exponent = exponent_zero;
0378          return *this;
0379       case FP_NAN:
0380          m_data     = limb_type(0);
0381          m_sign     = false;
0382          m_exponent = exponent_nan;
0383          return *this;
0384       case FP_INFINITE:
0385          m_data     = limb_type(0);
0386          m_sign     = (f < 0);
0387          m_exponent = exponent_infinity;
0388          return *this;
0389       }
0390       if (f < 0)
0391       {
0392          *this = -f;
0393          this->negate();
0394          return *this;
0395       }
0396 
0397       using ui_type = typename std::tuple_element<0, unsigned_types>::type;
0398       m_data     = static_cast<ui_type>(0u);
0399       m_sign     = false;
0400       m_exponent = 0;
0401 
0402       constexpr std::ptrdiff_t bits = sizeof(int) * CHAR_BIT - 1;
0403       int e;
0404       f = frexp(f, &e);
0405       while (f != static_cast<Float>(0.0F))
0406       {
0407          f = ldexp(f, bits);
0408          e -= static_cast<int>(bits);
0409          int ipart = boost::multiprecision::detail::itrunc(f);
0410          f -= static_cast<Float>(ipart);
0411          m_exponent += static_cast<exponent_type>(bits);
0412          cpp_bin_float t;
0413          t = static_cast<bf_int_type>(ipart);
0414          eval_add(*this, t);
0415       }
0416       m_exponent += static_cast<Exponent>(e);
0417       return *this;
0418    }
0419 
0420    template <class Float>
0421    typename std::enable_if<
0422        (number_category<Float>::value == number_kind_floating_point) && !std::is_floating_point<Float>::value && (number_category<Float>::value == number_kind_floating_point),
0423        cpp_bin_float&>::type
0424    assign_float(Float f)
0425    {
0426       using default_ops::eval_add;
0427       using default_ops::eval_convert_to;
0428       using default_ops::eval_get_sign;
0429       using default_ops::eval_subtract;
0430 
0431       using f_int_type = typename boost::multiprecision::detail::canonical<int, Float>::type        ;
0432       using bf_int_type = typename boost::multiprecision::detail::canonical<int, cpp_bin_float>::type;
0433 
0434       switch (eval_fpclassify(f))
0435       {
0436       case FP_ZERO:
0437          m_data     = limb_type(0);
0438          m_sign     = (eval_get_sign(f) > 0);
0439          m_exponent = exponent_zero;
0440          return *this;
0441       case FP_NAN:
0442          m_data     = limb_type(0);
0443          m_sign     = false;
0444          m_exponent = exponent_nan;
0445          return *this;
0446       case FP_INFINITE:
0447          m_data     = limb_type(0);
0448          m_sign     = eval_get_sign(f) < 0;
0449          m_exponent = exponent_infinity;
0450          return *this;
0451       }
0452       if (eval_get_sign(f) < 0)
0453       {
0454          f.negate();
0455          assign_float(f);
0456          this->negate();
0457          return *this;
0458       }
0459 
0460       using ui_type = typename std::tuple_element<0, unsigned_types>::type;
0461       m_data     = static_cast<ui_type>(0u);
0462       m_sign     = false;
0463       m_exponent = 0;
0464 
0465       constexpr std::ptrdiff_t bits = sizeof(int) * CHAR_BIT - 1;
0466       int              e;
0467       eval_frexp(f, f, &e);
0468       while (eval_get_sign(f) != 0)
0469       {
0470          eval_ldexp(f, f, bits);
0471          e -= bits;
0472          int ipart;
0473          eval_convert_to(&ipart, f);
0474          eval_subtract(f, static_cast<f_int_type>(ipart));
0475          m_exponent += bits;
0476          eval_add(*this, static_cast<bf_int_type>(ipart));
0477       }
0478       m_exponent += e;
0479       if (m_exponent > max_exponent)
0480          m_exponent = exponent_infinity;
0481       if (m_exponent < min_exponent)
0482       {
0483          m_data     = limb_type(0u);
0484          m_exponent = exponent_zero;
0485          m_sign     = (eval_get_sign(f) > 0);
0486       }
0487       else if (eval_get_sign(m_data) == 0)
0488       {
0489          m_exponent = exponent_zero;
0490          m_sign     = (eval_get_sign(f) > 0);
0491       }
0492       return *this;
0493    }
0494    template <class B, expression_template_option et>
0495    cpp_bin_float& assign_float(const number<B, et>& f)
0496    {
0497       return assign_float(f.backend());
0498    }
0499    
0500    template <class I>
0501    typename std::enable_if<boost::multiprecision::detail::is_integral<I>::value, cpp_bin_float&>::type operator=(const I& i)
0502    {
0503       using default_ops::eval_bit_test;
0504       if (!i)
0505       {
0506          m_data     = static_cast<limb_type>(0);
0507          m_exponent = exponent_zero;
0508          m_sign     = false;
0509       }
0510       else
0511       {
0512          using ui_type = typename boost::multiprecision::detail::make_unsigned<I>::type                                      ;
0513          ui_type                                                                            fi = static_cast<ui_type>(boost::multiprecision::detail::unsigned_abs(i));
0514          using ar_type = typename boost::multiprecision::detail::canonical<ui_type, rep_type>::type;
0515          m_data         = static_cast<ar_type>(fi);
0516          std::size_t shift = msb(fi);
0517          if (shift >= bit_count)
0518          {
0519             m_exponent = static_cast<Exponent>(shift);
0520             m_data     = static_cast<ar_type>(fi >> (shift + 1 - bit_count));
0521          }
0522          else
0523          {
0524             m_exponent = static_cast<Exponent>(shift);
0525             eval_left_shift(m_data, bit_count - shift - 1);
0526          }
0527          BOOST_MP_ASSERT(eval_bit_test(m_data, bit_count - 1));
0528          m_sign = detail::is_negative(i);
0529       }
0530       return *this;
0531    }
0532 
0533    cpp_bin_float& operator=(const char* s);
0534 
0535    void swap(cpp_bin_float& o) noexcept
0536    {
0537       m_data.swap(o.m_data);
0538       std::swap(m_exponent, o.m_exponent);
0539       std::swap(m_sign, o.m_sign);
0540    }
0541 
0542    std::string str(std::streamsize dig, std::ios_base::fmtflags f) const;
0543 
0544    void negate()
0545    {
0546       if (m_exponent != exponent_nan)
0547          m_sign = !m_sign;
0548    }
0549 
0550    int compare(const cpp_bin_float& o) const noexcept
0551    {
0552       if (m_sign != o.m_sign)
0553          return (m_exponent == exponent_zero) && (m_exponent == o.m_exponent) ? 0 : m_sign ? -1 : 1;
0554       int result;
0555       if (m_exponent == exponent_nan)
0556          return -1;
0557       else if (m_exponent != o.m_exponent)
0558       {
0559          if (m_exponent == exponent_zero)
0560             result = -1;
0561          else if (o.m_exponent == exponent_zero)
0562             result = 1;
0563          else
0564             result = m_exponent > o.m_exponent ? 1 : -1;
0565       }
0566       else
0567          result = m_data.compare(o.m_data);
0568       if (m_sign)
0569          result = -result;
0570       return result;
0571    }
0572    template <class A>
0573    int compare(const A& o) const noexcept
0574    {
0575       cpp_bin_float b;
0576       b = o;
0577       return compare(b);
0578    }
0579 
0580    rep_type&            bits() { return m_data; }
0581    const rep_type&      bits() const { return m_data; }
0582    exponent_type&       exponent() { return m_exponent; }
0583    const exponent_type& exponent() const { return m_exponent; }
0584    bool&                sign() { return m_sign; }
0585    const bool&          sign() const { return m_sign; }
0586    void                 check_invariants()
0587    {
0588       using default_ops::eval_bit_test;
0589       using default_ops::eval_is_zero;
0590       if ((m_exponent <= max_exponent) && (m_exponent >= min_exponent))
0591       {
0592          BOOST_MP_ASSERT(eval_bit_test(m_data, bit_count - 1));
0593       }
0594       else
0595       {
0596          BOOST_MP_ASSERT(m_exponent > max_exponent);
0597          BOOST_MP_ASSERT(m_exponent <= exponent_nan);
0598          BOOST_MP_ASSERT(eval_is_zero(m_data));
0599       }
0600    }
0601 
0602    #ifndef BOOST_MP_STANDALONE
0603    template <class Archive>
0604    void serialize(Archive& ar, const unsigned int /*version*/)
0605    {
0606       ar& boost::make_nvp("data", m_data);
0607       ar& boost::make_nvp("exponent", m_exponent);
0608       ar& boost::make_nvp("sign", m_sign);
0609    }
0610    #endif
0611 };
0612 
0613 #ifdef BOOST_MSVC
0614 #pragma warning(pop)
0615 #endif
0616 
0617 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class Int>
0618 inline void copy_and_round(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, Int& arg, std::ptrdiff_t bits_to_keep = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)
0619 {
0620    // Precondition: exponent of res must have been set before this function is called
0621    // as we may need to adjust it based on how many bits_to_keep in arg are set.
0622    using default_ops::eval_bit_test;
0623    using default_ops::eval_get_sign;
0624    using default_ops::eval_increment;
0625    using default_ops::eval_left_shift;
0626    using default_ops::eval_lsb;
0627    using default_ops::eval_msb;
0628    using default_ops::eval_right_shift;
0629 
0630    // cancellation may have resulted in arg being all zeros:
0631    if (eval_get_sign(arg) == 0)
0632    {
0633       res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
0634       res.sign()     = false;
0635       res.bits()     = static_cast<limb_type>(0u);
0636       return;
0637    }
0638    std::ptrdiff_t msb = static_cast<std::ptrdiff_t>(eval_msb(arg));
0639    if (static_cast<std::ptrdiff_t >(bits_to_keep) > msb + 1)
0640    {
0641       // Must have had cancellation in subtraction,
0642       // or be converting from a narrower type, so shift left:
0643       res.bits() = arg;
0644       eval_left_shift(res.bits(), static_cast<double_limb_type>(bits_to_keep - msb - 1));
0645       res.exponent() -= static_cast<Exponent>(bits_to_keep - msb - 1);
0646    }
0647    else if (static_cast<std::ptrdiff_t >(bits_to_keep) < msb + 1)
0648    {
0649       // We have more bits_to_keep than we need, so round as required,
0650       // first get the rounding bit:
0651       bool roundup = eval_bit_test(arg, static_cast<std::size_t>(msb - bits_to_keep));
0652       // Then check for a tie:
0653       if (roundup && (msb - bits_to_keep == static_cast<std::ptrdiff_t>(eval_lsb(arg))))
0654       {
0655          // Ties round towards even:
0656          if (!eval_bit_test(arg, static_cast<std::size_t>(msb - bits_to_keep + 1)))
0657             roundup = false;
0658       }
0659       // Shift off the bits_to_keep we don't need:
0660       eval_right_shift(arg, static_cast<double_limb_type>(msb - bits_to_keep + 1));
0661       res.exponent() += static_cast<Exponent>(msb - bits_to_keep + 1);
0662       if (roundup)
0663       {
0664          eval_increment(arg);
0665          if (bits_to_keep)
0666          {
0667             if (eval_bit_test(arg, static_cast<std::size_t>(bits_to_keep)))
0668             {
0669                // This happens very very rairly, all the bits left after
0670                // truncation must be 1's and we're rounding up an order of magnitude:
0671                eval_right_shift(arg, 1u);
0672                ++res.exponent();
0673             }
0674          }
0675          else
0676          {
0677             // We get here when bits_to_keep is zero but we're rounding up,
0678             // as a result we end up with a single digit that is a 1:
0679             ++bits_to_keep;
0680          }
0681       }
0682       if (bits_to_keep != cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)
0683       {
0684          // Normalize result when we're rounding to fewer bits than we can hold, only happens in conversions
0685          // to narrower types:
0686          eval_left_shift(arg, static_cast<double_limb_type>(static_cast<std::ptrdiff_t>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) - bits_to_keep));
0687          res.exponent() -= static_cast<Exponent>(static_cast<std::ptrdiff_t>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) - bits_to_keep);
0688       }
0689       res.bits() = arg;
0690    }
0691    else
0692    {
0693       res.bits() = arg;
0694    }
0695    if (!bits_to_keep && !res.bits().limbs()[0])
0696    {
0697       // We're keeping zero bits and did not round up, so result is zero:
0698       res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
0699       return;
0700    }
0701    // Result must be normalized:
0702    BOOST_MP_ASSERT(((std::ptrdiff_t )eval_msb(res.bits()) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1));
0703 
0704    if (res.exponent() > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent)
0705    {
0706       // Overflow:
0707       res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
0708       res.bits()     = static_cast<limb_type>(0u);
0709    }
0710    else if (res.exponent() < cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent)
0711    {
0712       // Underflow:
0713       res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
0714       res.bits()     = static_cast<limb_type>(0u);
0715    }
0716 }
0717 
0718 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class BinFloat2, class BinFloat3>
0719 inline void do_eval_add(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, 
0720    const BinFloat2& a, const BinFloat3& b)
0721 {
0722    if (a.exponent() < b.exponent())
0723    {
0724       bool s = a.sign();
0725       do_eval_add(res, b, a);
0726       if (res.sign() != s)
0727          res.negate();
0728       return;
0729    }
0730 
0731    using default_ops::eval_add;
0732    using default_ops::eval_bit_test;
0733 
0734    using exponent_type = typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type;
0735 
0736    typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type dt;
0737 
0738    // Special cases first:
0739    switch (a.exponent())
0740    {
0741    case BinFloat2::exponent_zero:
0742    {
0743       bool s     = a.sign();
0744       res        = b;
0745       res.sign() = s;
0746       return;
0747    }
0748    case BinFloat2::exponent_infinity:
0749       if (b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan)
0750          res = b;
0751       else
0752          res = a;
0753       return; // result is still infinite.
0754    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
0755       res = a;
0756       return; // result is still a NaN.
0757    }
0758    switch (b.exponent())
0759    {
0760    case BinFloat3::exponent_zero:
0761       res = a;
0762       return;
0763    case BinFloat3::exponent_infinity:
0764       res = b;
0765       if (res.sign())
0766          res.negate();
0767       return; // result is infinite.
0768    case BinFloat3::exponent_nan:
0769       res = b;
0770       return; // result is a NaN.
0771    }
0772 
0773    static_assert((std::numeric_limits<exponent_type>::max)() - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent, "Exponent range check failed");
0774 
0775    bool s = a.sign();
0776    dt     = a.bits();
0777    if (a.exponent() > (std::ptrdiff_t )cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + b.exponent())
0778    {
0779       res.exponent() = a.exponent();
0780    }
0781    else
0782    {
0783       exponent_type e_diff = a.exponent() - b.exponent();
0784       BOOST_MP_ASSERT(e_diff >= 0);
0785       eval_left_shift(dt, static_cast<double_limb_type>(e_diff));
0786       res.exponent() = a.exponent() - e_diff;
0787       eval_add(dt, b.bits());
0788    }
0789 
0790    copy_and_round(res, dt);
0791    res.check_invariants();
0792    if (res.sign() != s)
0793       res.negate();
0794 }
0795 
0796 template <class BinFloat1, class BinFloat2, class BinFloat3>
0797 inline void do_eval_subtract(BinFloat1& res, const BinFloat2& a, const BinFloat3& b)
0798 {
0799    using default_ops::eval_bit_test;
0800    using default_ops::eval_decrement;
0801    using default_ops::eval_subtract;
0802 
0803    typename BinFloat1::double_rep_type dt;
0804 
0805    // Special cases first:
0806    switch (a.exponent())
0807    {
0808    case BinFloat2::exponent_zero:
0809       if (b.exponent() == BinFloat3::exponent_nan)
0810          res = std::numeric_limits<number<BinFloat1> >::quiet_NaN().backend();
0811       else
0812       {
0813          bool s = a.sign();
0814          res    = b;
0815          if (res.exponent() == BinFloat1::exponent_zero)
0816             res.sign() = false;
0817          else if (res.sign() == s)
0818             res.negate();
0819       }
0820       return;
0821    case BinFloat2::exponent_infinity:
0822       if ((b.exponent() == BinFloat3::exponent_nan) || (b.exponent() == BinFloat3::exponent_infinity))
0823          res = std::numeric_limits<number<BinFloat1> >::quiet_NaN().backend();
0824       else
0825          res = a;
0826       return;
0827    case BinFloat2::exponent_nan:
0828       res = a;
0829       return; // result is still a NaN.
0830    }
0831    switch (b.exponent())
0832    {
0833    case BinFloat3::exponent_zero:
0834       res = a;
0835       return;
0836    case BinFloat3::exponent_infinity:
0837       res.exponent() = BinFloat1::exponent_infinity;
0838       res.sign()     = !a.sign();
0839       res.bits()     = static_cast<limb_type>(0u);
0840       return; // result is a NaN.
0841    case BinFloat3::exponent_nan:
0842       res = b;
0843       return; // result is still a NaN.
0844    }
0845 
0846    bool s = a.sign();
0847    if ((a.exponent() > b.exponent()) || ((a.exponent() == b.exponent()) && a.bits().compare(b.bits()) >= 0))
0848    {
0849       dt = a.bits();
0850       if (a.exponent() <= (std::ptrdiff_t )BinFloat1::bit_count + b.exponent())
0851       {
0852          typename BinFloat1::exponent_type e_diff = a.exponent() - b.exponent();
0853          eval_left_shift(dt, static_cast<double_limb_type>(e_diff));
0854          res.exponent() = a.exponent() - e_diff;
0855          eval_subtract(dt, b.bits());
0856       }
0857       else if (a.exponent() == (std::ptrdiff_t )BinFloat1::bit_count + b.exponent() + 1)
0858       {
0859          if ((eval_lsb(a.bits()) == BinFloat1::bit_count - 1)
0860             && (eval_lsb(b.bits()) != BinFloat1::bit_count - 1))
0861          {
0862             eval_left_shift(dt, 1);
0863             eval_decrement(dt);
0864             res.exponent() = a.exponent() - 1;
0865          }
0866          else
0867             res.exponent() = a.exponent();
0868       }
0869       else
0870          res.exponent() = a.exponent();
0871    }
0872    else
0873    {
0874       dt = b.bits();
0875       if (b.exponent() <= (std::ptrdiff_t )BinFloat1::bit_count + a.exponent())
0876       {
0877          typename BinFloat1::exponent_type e_diff = a.exponent() - b.exponent();
0878          eval_left_shift(dt, static_cast<double_limb_type>(-e_diff));
0879          res.exponent() = b.exponent() + e_diff;
0880          eval_subtract(dt, a.bits());
0881       }
0882       else if (b.exponent() == (std::ptrdiff_t )BinFloat1::bit_count + a.exponent() + 1)
0883       {
0884          if ((eval_lsb(a.bits()) != BinFloat1::bit_count - 1)
0885             && eval_lsb(b.bits()))
0886          {
0887             eval_left_shift(dt, 1);
0888             eval_decrement(dt);
0889             res.exponent() = b.exponent() - 1;
0890          }
0891          else
0892             res.exponent() = b.exponent();
0893       }
0894       else
0895          res.exponent() = b.exponent();
0896       s = !s;
0897    }
0898 
0899    copy_and_round(res, dt);
0900    if (res.exponent() == BinFloat1::exponent_zero)
0901       res.sign() = false;
0902    else if (res.sign() != s)
0903       res.negate();
0904    res.check_invariants();
0905 }
0906 
0907 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, 
0908    class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2,
0909    class Allocator3, class Exponent3, Exponent MinE3, Exponent MaxE3>
0910 inline void eval_add(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, 
0911    const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& a, 
0912    const cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>& b)
0913 {
0914    if (a.sign() == b.sign())
0915       do_eval_add(res, a, b);
0916    else
0917       do_eval_subtract(res, a, b);
0918 }
0919 
0920 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
0921    class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2>
0922 inline void eval_add(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, 
0923    const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& a)
0924 {
0925    return eval_add(res, res, a);
0926 }
0927 
0928 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
0929    class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2,
0930    class Allocator3, class Exponent3, Exponent MinE3, Exponent MaxE3>
0931 inline void eval_subtract(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, 
0932    const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& a, 
0933    const cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>& b)
0934 {
0935    if (a.sign() != b.sign())
0936       do_eval_add(res, a, b);
0937    else
0938       do_eval_subtract(res, a, b);
0939 }
0940 
0941 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
0942    class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2>
0943 inline void eval_subtract(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, 
0944    const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& a)
0945 {
0946    return eval_subtract(res, res, a);
0947 }
0948 
0949 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, 
0950    class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2, 
0951    class Allocator3, class Exponent3, Exponent MinE3, Exponent MaxE3>
0952 inline void eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, 
0953    const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& a, 
0954    const cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>& b)
0955 {
0956    using default_ops::eval_bit_test;
0957    using default_ops::eval_multiply;
0958 
0959    // Special cases first:
0960    switch (a.exponent())
0961    {
0962    case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_zero:
0963    {
0964       if (b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_nan)
0965          res = b;
0966       else if (b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_infinity)
0967          res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
0968       else
0969       {
0970          bool s     = a.sign() != b.sign();
0971          res        = a;
0972          res.sign() = s;
0973       }
0974       return;
0975    }
0976    case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_infinity:
0977       switch (b.exponent())
0978       {
0979       case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_zero:
0980          res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
0981          break;
0982       case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_nan:
0983          res = b;
0984          break;
0985       default:
0986          bool s     = a.sign() != b.sign();
0987          res        = a;
0988          res.sign() = s;
0989          break;
0990       }
0991       return;
0992    case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_nan:
0993       res = a;
0994       return;
0995    }
0996    if (b.exponent() > cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::max_exponent)
0997    {
0998       bool s     = a.sign() != b.sign();
0999       res        = b;
1000       res.sign() = s;
1001       return;
1002    }
1003    if ((a.exponent() > 0) && (b.exponent() > 0))
1004    {
1005       if (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent + 2 - a.exponent() < b.exponent())
1006       {
1007          // We will certainly overflow:
1008          bool s         = a.sign() != b.sign();
1009          res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
1010          res.sign()     = s;
1011          res.bits()     = static_cast<limb_type>(0u);
1012          return;
1013       }
1014    }
1015    if ((a.exponent() < 0) && (b.exponent() < 0))
1016    {
1017       if (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent - 2 - a.exponent() > b.exponent())
1018       {
1019          // We will certainly underflow:
1020          res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
1021          res.sign()     = a.sign() != b.sign();
1022          res.bits()     = static_cast<limb_type>(0u);
1023          return;
1024       }
1025    }
1026 
1027    typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type dt;
1028    eval_multiply(dt, a.bits(), b.bits());
1029    res.exponent() = a.exponent() + b.exponent() - (Exponent)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 1;
1030    copy_and_round(res, dt);
1031    res.check_invariants();
1032    res.sign() = a.sign() != b.sign();
1033 }
1034 
1035 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
1036    class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2>
1037 inline void eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, 
1038    const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& a)
1039 {
1040    eval_multiply(res, res, a);
1041 }
1042 
1043 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
1044    class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2, class U>
1045 inline typename std::enable_if<boost::multiprecision::detail::is_unsigned<U>::value>::type eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, 
1046    const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& a, const U& b)
1047 {
1048    using default_ops::eval_bit_test;
1049    using default_ops::eval_multiply;
1050 
1051    bool s = a.sign(); // saved for later in case a and res are the same object.
1052 
1053    // Special cases first:
1054    switch (a.exponent())
1055    {
1056    case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_zero:
1057    {
1058       res        = a;
1059       res.sign() = s;
1060       return;
1061    }
1062    case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_infinity:
1063       if (b == 0)
1064          res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
1065       else
1066          res = a;
1067       return;
1068    case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_nan:
1069       res = a;
1070       return;
1071    }
1072 
1073    typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type                                                                     dt;
1074    using canon_ui_type = typename boost::multiprecision::detail::canonical<U, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type>::type;
1075    eval_multiply(dt, a.bits(), static_cast<canon_ui_type>(b));
1076    res.exponent() = a.exponent();
1077    copy_and_round(res, dt);
1078    res.check_invariants();
1079    res.sign() = s;
1080 }
1081 
1082 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class U>
1083 inline typename std::enable_if<boost::multiprecision::detail::is_unsigned<U>::value>::type eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const U& b)
1084 {
1085    eval_multiply(res, res, b);
1086 }
1087 
1088 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
1089    class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2, class S>
1090 inline typename std::enable_if<boost::multiprecision::detail::is_signed<S>::value && boost::multiprecision::detail::is_integral<S>::value>::type eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, 
1091    const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& a, const S& b)
1092 {
1093    using ui_type = typename boost::multiprecision::detail::make_unsigned<S>::type;
1094    eval_multiply(res, a, static_cast<ui_type>(boost::multiprecision::detail::unsigned_abs(b)));
1095    if (b < 0)
1096       res.negate();
1097 }
1098 
1099 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class S>
1100 inline typename std::enable_if<boost::multiprecision::detail::is_signed<S>::value && boost::multiprecision::detail::is_integral<S>::value>::type eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const S& b)
1101 {
1102    eval_multiply(res, res, b);
1103 }
1104 
1105 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
1106    class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2,
1107    class Allocator3, class Exponent3, Exponent MinE3, Exponent MaxE3>
1108 inline void eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, 
1109    const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& u, 
1110    const cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>& v)
1111 {
1112 #ifdef BOOST_MSVC
1113 #pragma warning(push)
1114 #pragma warning(disable : 6326) // comparison of two constants
1115 #endif
1116    using default_ops::eval_bit_test;
1117    using default_ops::eval_get_sign;
1118    using default_ops::eval_increment;
1119    using default_ops::eval_qr;
1120    using default_ops::eval_subtract;
1121 
1122    //
1123    // Special cases first:
1124    //
1125    switch (u.exponent())
1126    {
1127    case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_zero:
1128    {
1129       switch (v.exponent())
1130       {
1131       case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_zero:
1132       case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_nan:
1133          res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
1134          return;
1135       }
1136       bool s     = u.sign() != v.sign();
1137       res        = u;
1138       res.sign() = s;
1139       return;
1140    }
1141    case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_infinity:
1142    {
1143       switch (v.exponent())
1144       {
1145       case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_infinity:
1146       case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_nan:
1147          res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
1148          return;
1149       }
1150       bool s     = u.sign() != v.sign();
1151       res        = u;
1152       res.sign() = s;
1153       return;
1154    }
1155    case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_nan:
1156       res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
1157       return;
1158    }
1159    switch (v.exponent())
1160    {
1161    case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_zero:
1162    {
1163       bool s     = u.sign() != v.sign();
1164       res        = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend();
1165       res.sign() = s;
1166       return;
1167    }
1168    case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_infinity:
1169       res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
1170       res.bits()     = limb_type(0);
1171       res.sign()     = u.sign() != v.sign();
1172       return;
1173    case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_nan:
1174       res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
1175       return;
1176    }
1177 
1178    // We can scale u and v so that both are integers, then perform integer
1179    // division to obtain quotient q and remainder r, such that:
1180    //
1181    // q * v + r = u
1182    //
1183    // and hense:
1184    //
1185    // q + r/v = u/v
1186    //
1187    // From this, assuming q has cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count
1188    // bits we only need to determine whether
1189    // r/v is less than, equal to, or greater than 0.5 to determine rounding -
1190    // this we can do with a shift and comparison.
1191    //
1192    // We can set the exponent and sign of the result up front:
1193    //
1194    if ((v.exponent() < 0) && (u.exponent() > 0))
1195    {
1196       // Check for overflow:
1197       if (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent + v.exponent() < u.exponent() - 1)
1198       {
1199          res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
1200          res.sign()     = u.sign() != v.sign();
1201          res.bits()     = static_cast<limb_type>(0u);
1202          return;
1203       }
1204    }
1205    else if ((v.exponent() > 0) && (u.exponent() < 0))
1206    {
1207       // Check for underflow:
1208       if (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent + v.exponent() > u.exponent())
1209       {
1210          // We will certainly underflow:
1211          res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
1212          res.sign()     = u.sign() != v.sign();
1213          res.bits()     = static_cast<limb_type>(0u);
1214          return;
1215       }
1216    }
1217    res.exponent() = u.exponent() - v.exponent() - 1;
1218    res.sign()     = u.sign() != v.sign();
1219    //
1220    // Now get the quotient and remainder:
1221    //
1222    typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type t(u.bits()), t2(v.bits()), q, r;
1223    eval_left_shift(t, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count);
1224    eval_qr(t, t2, q, r);
1225    //
1226    // We now have either "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count"
1227    // or "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count+1" significant
1228    // bits in q.
1229    //
1230    constexpr unsigned limb_bits = sizeof(limb_type) * CHAR_BIT;
1231    if (eval_bit_test(q, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count))
1232    {
1233       //
1234       // OK we have cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count+1 bits,
1235       // so we already have rounding info,
1236       // we just need to changes things if the last bit is 1 and either the
1237       // remainder is non-zero (ie we do not have a tie) or the quotient would
1238       // be odd if it were shifted to the correct number of bits (ie a tiebreak).
1239       //
1240       BOOST_MP_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count));
1241       if ((q.limbs()[0] & 1u) && (eval_get_sign(r) || (q.limbs()[0] & 2u)))
1242       {
1243          eval_increment(q);
1244       }
1245    }
1246    else
1247    {
1248       //
1249       // We have exactly "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count" bits in q.
1250       // Get rounding info, which we can get by comparing 2r with v.
1251       // We want to call copy_and_round to handle rounding and general cleanup,
1252       // so we'll left shift q and add some fake digits on the end to represent
1253       // how we'll be rounding.
1254       //
1255       using local_exponent_type = typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type;
1256 
1257       BOOST_MP_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1));
1258       constexpr unsigned lshift = (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count < limb_bits) ? 2 : limb_bits;
1259       eval_left_shift(q, lshift);
1260       res.exponent() -= static_cast<local_exponent_type>(lshift);
1261       eval_left_shift(r, 1u);
1262       int c = r.compare(v.bits());
1263       if (c == 0)
1264          q.limbs()[0] |= static_cast<limb_type>(1u) << (lshift - 1);
1265       else if (c > 0)
1266          q.limbs()[0] |= (static_cast<limb_type>(1u) << (lshift - 1)) + static_cast<limb_type>(1u);
1267    }
1268    copy_and_round(res, q);
1269 #ifdef BOOST_MSVC
1270 #pragma warning(pop)
1271 #endif
1272 }
1273 
1274 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
1275    class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2>
1276 inline void eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, 
1277    const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& arg)
1278 {
1279    eval_divide(res, res, arg);
1280 }
1281 
1282 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
1283    class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2, class U>
1284 inline typename std::enable_if<boost::multiprecision::detail::is_unsigned<U>::value>::type eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, 
1285    const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& u, const U& v)
1286 {
1287 #ifdef BOOST_MSVC
1288 #pragma warning(push)
1289 #pragma warning(disable : 6326) // comparison of two constants
1290 #endif
1291    using default_ops::eval_bit_test;
1292    using default_ops::eval_get_sign;
1293    using default_ops::eval_increment;
1294    using default_ops::eval_qr;
1295    using default_ops::eval_subtract;
1296 
1297    //
1298    // Special cases first:
1299    //
1300    switch (u.exponent())
1301    {
1302    case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_zero:
1303    {
1304       if (v == 0)
1305       {
1306          res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
1307          return;
1308       }
1309       bool s     = u.sign() != (v < 0);
1310       res        = u;
1311       res.sign() = s;
1312       return;
1313    }
1314    case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_infinity:
1315       res = u;
1316       return;
1317    case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_nan:
1318       res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
1319       return;
1320    }
1321    if (v == 0)
1322    {
1323       bool s     = u.sign();
1324       res        = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend();
1325       res.sign() = s;
1326       return;
1327    }
1328 
1329    // We can scale u and v so that both are integers, then perform integer
1330    // division to obtain quotient q and remainder r, such that:
1331    //
1332    // q * v + r = u
1333    //
1334    // and hense:
1335    //
1336    // q + r/v = u/v
1337    //
1338    // From this, assuming q has "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count" cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count, we only need to determine whether
1339    // r/v is less than, equal to, or greater than 0.5 to determine rounding -
1340    // this we can do with a shift and comparison.
1341    //
1342    // We can set the exponent and sign of the result up front:
1343    //
1344    std::ptrdiff_t  gb         = static_cast<std::ptrdiff_t>(msb(v));
1345    res.exponent() = u.exponent() - static_cast<Exponent>(gb) - static_cast<Exponent>(1);
1346    res.sign()     = u.sign();
1347    //
1348    // Now get the quotient and remainder:
1349    //
1350    typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type t(u.bits()), q, r;
1351    eval_left_shift(t, static_cast<double_limb_type>(gb + 1));
1352    eval_qr(t, number<typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type>::canonical_value(v), q, r);
1353    //
1354    // We now have either "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count" or "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count+1" significant cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count in q.
1355    //
1356    constexpr unsigned limb_bits = sizeof(limb_type) * CHAR_BIT;
1357    if (eval_bit_test(q, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count))
1358    {
1359       //
1360       // OK we have cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count+1 cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count, so we already have rounding info,
1361       // we just need to changes things if the last bit is 1 and the
1362       // remainder is non-zero (ie we do not have a tie).
1363       //
1364       BOOST_MP_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count));
1365       if ((q.limbs()[0] & 1u) && eval_get_sign(r))
1366       {
1367          eval_increment(q);
1368       }
1369    }
1370    else
1371    {
1372       //
1373       // We have exactly "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count" cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count in q.
1374       // Get rounding info, which we can get by comparing 2r with v.
1375       // We want to call copy_and_round to handle rounding and general cleanup,
1376       // so we'll left shift q and add some fake cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count on the end to represent
1377       // how we'll be rounding.
1378       //
1379       using local_exponent_type = typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type;
1380 
1381       BOOST_MP_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1));
1382       constexpr unsigned lshift = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count < limb_bits ? 2 : limb_bits;
1383       eval_left_shift(q, lshift);
1384       res.exponent() -= static_cast<local_exponent_type>(lshift);
1385       eval_left_shift(r, 1u);
1386       int c = r.compare(number<typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type>::canonical_value(v));
1387       if (c == 0)
1388          q.limbs()[0] |= static_cast<limb_type>(1u) << (lshift - 1);
1389       else if (c > 0)
1390          q.limbs()[0] |= (static_cast<limb_type>(1u) << (lshift - 1)) + static_cast<limb_type>(1u);
1391    }
1392    copy_and_round(res, q);
1393 #ifdef BOOST_MSVC
1394 #pragma warning(pop)
1395 #endif
1396 }
1397 
1398 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class U>
1399 inline typename std::enable_if<boost::multiprecision::detail::is_unsigned<U>::value>::type eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const U& v)
1400 {
1401    eval_divide(res, res, v);
1402 }
1403 
1404 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
1405    class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2, class S>
1406 inline typename std::enable_if<boost::multiprecision::detail::is_signed<S>::value && boost::multiprecision::detail::is_integral<S>::value>::type eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, 
1407    const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& u, const S& v)
1408 {
1409    using ui_type = typename boost::multiprecision::detail::make_unsigned<S>::type;
1410    eval_divide(res, u, static_cast<ui_type>(boost::multiprecision::detail::unsigned_abs(v)));
1411    if (v < 0)
1412       res.negate();
1413 }
1414 
1415 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class S>
1416 inline typename std::enable_if<boost::multiprecision::detail::is_signed<S>::value && boost::multiprecision::detail::is_integral<S>::value>::type eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const S& v)
1417 {
1418    eval_divide(res, res, v);
1419 }
1420 
1421 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1422 inline int eval_get_sign(const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1423 {
1424    return arg.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero ? 0 : arg.sign() ? -1 : 1;
1425 }
1426 
1427 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1428 inline bool eval_is_zero(const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1429 {
1430    return arg.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
1431 }
1432 
1433 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1434 inline bool eval_eq(const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& a, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& b)
1435 {
1436    if (a.exponent() == b.exponent())
1437    {
1438       if (a.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero)
1439          return true;
1440       return (a.sign() == b.sign()) && (a.bits().compare(b.bits()) == 0) && (a.exponent() != cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan);
1441    }
1442    return false;
1443 }
1444 
1445 template <class I, unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1446 inline void convert_to_signed_int(I* res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1447 {
1448    static constexpr int digits  = std::numeric_limits<I>::is_specialized ? std::numeric_limits<I>::digits : sizeof(I) * CHAR_BIT - 1;
1449    static constexpr I max_val = std::numeric_limits<I>::is_specialized ? (std::numeric_limits<I>::max)() : (((I(1) << (sizeof(I) * CHAR_BIT - 2)) - 1) << 1) + 1;
1450    static constexpr I min_val = std::numeric_limits<I>::is_specialized ? (std::numeric_limits<I>::min)() : -max_val - 1;
1451 
1452 
1453    switch (arg.exponent())
1454    {
1455    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1456       *res = 0;
1457       return;
1458    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1459       BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
1460       return;
1461    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1462       *res = max_val;
1463       if (arg.sign())
1464          *res = -*res;
1465       return;
1466    }
1467    using shift_type = typename std::conditional<sizeof(typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type) < sizeof(int), int, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type>::type;
1468    typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::rep_type man(arg.bits());
1469    shift_type                                                                           shift = (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 - arg.exponent();
1470    if (shift > (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1)
1471    {
1472       *res = 0;
1473       return;
1474    }
1475    if (arg.sign() && (arg.compare(min_val) <= 0))
1476    {
1477       *res = min_val;
1478       return;
1479    }
1480    else if (!arg.sign() && (arg.compare(max_val) >= 0))
1481    {
1482       *res = max_val;
1483       return;
1484    }
1485 
1486    if (shift < 0)
1487    {
1488       if (static_cast<int>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) - static_cast<int>(shift) <= digits)
1489       {
1490          // We have more bits in long_long_type than the float, so it's OK to left shift:
1491          eval_convert_to(res, man);
1492          *res <<= -shift;
1493       }
1494       else
1495       {
1496          *res = (std::numeric_limits<I>::max)();
1497          return;
1498       }
1499    }
1500    else
1501    {
1502       eval_right_shift(man, static_cast<double_limb_type>(shift));
1503       eval_convert_to(res, man);
1504    }
1505    if (arg.sign())
1506    {
1507       *res = -*res;
1508    }
1509 }
1510 
1511 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1512 inline void eval_convert_to(long long* res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1513 {
1514    convert_to_signed_int(res, arg);
1515 }
1516 
1517 #ifdef BOOST_HAS_INT128
1518 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1519 inline void eval_convert_to(int128_type* res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1520 {
1521    convert_to_signed_int(res, arg);
1522 }
1523 #endif
1524 
1525 template <class I, unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1526 inline void convert_to_unsigned_int(I* res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1527 {
1528    static constexpr int digits  = std::numeric_limits<I>::is_specialized ? std::numeric_limits<I>::digits : sizeof(I) * CHAR_BIT;
1529    static constexpr I   max_val = std::numeric_limits<I>::is_specialized ? (std::numeric_limits<I>::max)() : ~static_cast<I>(0);
1530 
1531    switch (arg.exponent())
1532    {
1533    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1534       *res = 0;
1535       return;
1536    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1537       BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
1538    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1539       *res = max_val;
1540       return;
1541    }
1542    typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::rep_type                                                                                                                                                              man(arg.bits());
1543    using shift_type = typename std::conditional<sizeof(typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type) < sizeof(int), int, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type>::type;
1544    shift_type                                                                                                                                                                                                                                        shift = (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 - arg.exponent();
1545    if (shift > (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1)
1546    {
1547       *res = 0;
1548       return;
1549    }
1550    else if (shift < 0)
1551    {
1552       if (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - shift <= digits)
1553       {
1554          // We have more bits in ulong_long_type than the float, so it's OK to left shift:
1555          eval_convert_to(res, man);
1556          *res <<= -shift;
1557          return;
1558       }
1559       *res = max_val;
1560       return;
1561    }
1562    eval_right_shift(man, shift);
1563    eval_convert_to(res, man);
1564 }
1565 
1566 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1567 inline void eval_convert_to(unsigned long long* res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1568 {
1569    convert_to_unsigned_int(res, arg);
1570 }
1571 
1572 #ifdef BOOST_HAS_INT128
1573 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1574 inline void eval_convert_to(uint128_type* res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1575 {
1576    convert_to_unsigned_int(res, arg);
1577 }
1578 #endif
1579 
1580 template <class Float, unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1581 inline typename std::enable_if<std::is_floating_point<Float>::value>::type eval_convert_to(Float* res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& original_arg)
1582 {
1583    using conv_type = cpp_bin_float<std::numeric_limits<Float>::digits, digit_base_2, void, Exponent, MinE, MaxE>;
1584    using common_exp_type = typename std::common_type<typename conv_type::exponent_type, int>::type;
1585 
1586    static constexpr int float_digits = boost::multiprecision::detail::is_float128<Float>::value ? 113 : std::numeric_limits<Float>::digits;
1587 
1588    BOOST_MP_FLOAT128_USING using std::ldexp;
1589    //
1590    // Special cases first:
1591    //
1592    switch (original_arg.exponent())
1593    {
1594    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1595       *res = 0;
1596       if (original_arg.sign())
1597          *res = -*res;
1598       return;
1599    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1600       BOOST_IF_CONSTEXPR(boost::multiprecision::detail::is_float128<Float>::value)
1601       {
1602          *res = static_cast<Float>(std::numeric_limits<double>::quiet_NaN());
1603       }
1604       else
1605       {
1606          *res = std::numeric_limits<Float>::quiet_NaN();
1607       }
1608       return;
1609    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1610       BOOST_IF_CONSTEXPR(boost::multiprecision::detail::is_float128<Float>::value)
1611       {
1612          *res = static_cast<Float>((std::numeric_limits<double>::infinity)());
1613       }
1614       else
1615       {
1616          *res = (std::numeric_limits<Float>::infinity)();
1617       }
1618       if (original_arg.sign())
1619          *res = -*res;
1620       return;
1621    }
1622    //
1623    // Check for super large exponent that must be converted to infinity:
1624    //
1625    if (original_arg.exponent() > (boost::multiprecision::detail::is_float128<Float>::value ? 16384 : std::numeric_limits<Float>::max_exponent))
1626    {
1627       BOOST_IF_CONSTEXPR(boost::multiprecision::detail::is_float128<Float>::value)
1628       {
1629          *res = static_cast<Float>(std::numeric_limits<double>::infinity());
1630       }
1631       else
1632       {
1633          *res = std::numeric_limits<Float>::has_infinity ? std::numeric_limits<Float>::infinity() : (std::numeric_limits<Float>::max)();
1634       }
1635       if (original_arg.sign())
1636          *res = -*res;
1637       return;
1638    }
1639    //
1640    // Figure out how many digits we will have in our result,
1641    // allowing for a possibly denormalized result:
1642    //
1643    common_exp_type digits_to_round_to = float_digits;
1644    if (original_arg.exponent() < std::numeric_limits<Float>::min_exponent - 1)
1645    {
1646       common_exp_type diff = original_arg.exponent();
1647       diff -= boost::multiprecision::detail::is_float128<Float>::value ? -16382 : std::numeric_limits<Float>::min_exponent - 1;
1648       digits_to_round_to += diff;
1649    }
1650    if (digits_to_round_to < 0)
1651    {
1652       // Result must be zero:
1653       *res = 0;
1654       if (original_arg.sign())
1655          *res = -*res;
1656       return;
1657    }
1658    //
1659    // Perform rounding first, then afterwards extract the digits:
1660    //
1661    cpp_bin_float<static_cast<unsigned>(float_digits), digit_base_2, Allocator, Exponent, MinE, MaxE>           arg;
1662    typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::rep_type bits(original_arg.bits());
1663    arg.exponent() = original_arg.exponent();
1664    copy_and_round(arg, bits, (std::ptrdiff_t)digits_to_round_to);
1665    common_exp_type e = arg.exponent();
1666    e -= static_cast<common_exp_type>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) - 1;
1667    constexpr std::size_t limbs_needed      = static_cast<std::size_t>(float_digits) / (sizeof(*arg.bits().limbs()) * CHAR_BIT) + (static_cast<std::size_t>(float_digits) % (sizeof(*arg.bits().limbs()) * CHAR_BIT) ? 1 : 0);
1668    std::size_t                 first_limb_needed = arg.bits().size() - limbs_needed;
1669    *res                                          = 0;
1670    e += static_cast<common_exp_type>(first_limb_needed * sizeof(*arg.bits().limbs()) * CHAR_BIT);
1671    while (first_limb_needed < arg.bits().size())
1672    {
1673       *res += ldexp(static_cast<Float>(arg.bits().limbs()[first_limb_needed]), static_cast<int>(e));
1674       ++first_limb_needed;
1675       e += static_cast<common_exp_type>(sizeof(*arg.bits().limbs()) * CHAR_BIT);
1676    }
1677    if (original_arg.sign())
1678       *res = -*res;
1679 }
1680 
1681 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1682 inline void eval_frexp(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg, Exponent* e)
1683 {
1684    switch (arg.exponent())
1685    {
1686    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1687    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1688    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1689       *e  = 0;
1690       res = arg;
1691       return;
1692    }
1693    res            = arg;
1694    *e             = arg.exponent() + 1;
1695    res.exponent() = -1;
1696 }
1697 
1698 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class I>
1699 inline void eval_frexp(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg, I* pe)
1700 {
1701    Exponent e;
1702    eval_frexp(res, arg, &e);
1703    if ((e > (std::numeric_limits<I>::max)()) || (e < (std::numeric_limits<I>::min)()))
1704    {
1705       BOOST_MP_THROW_EXCEPTION(std::runtime_error("Exponent was outside of the range of the argument type to frexp."));
1706    }
1707    *pe = static_cast<I>(e);
1708 }
1709 
1710 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1711 inline void eval_ldexp(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg, Exponent e)
1712 {
1713    switch (arg.exponent())
1714    {
1715    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1716    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1717    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1718       res = arg;
1719       return;
1720    }
1721    if ((e > 0) && (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent - e < arg.exponent()))
1722    {
1723       // Overflow:
1724       res        = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend();
1725       res.sign() = arg.sign();
1726    }
1727    else if ((e < 0) && (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent - e > arg.exponent()))
1728    {
1729       // Underflow:
1730       res = limb_type(0);
1731    }
1732    else
1733    {
1734       res = arg;
1735       res.exponent() += e;
1736    }
1737 }
1738 
1739 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class I>
1740 inline typename std::enable_if<boost::multiprecision::detail::is_unsigned<I>::value>::type eval_ldexp(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg, I e)
1741 {
1742    using si_type = typename boost::multiprecision::detail::make_signed<I>::type;
1743    if (e > static_cast<I>((std::numeric_limits<si_type>::max)()))
1744       res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend();
1745    else
1746       eval_ldexp(res, arg, static_cast<si_type>(e));
1747 }
1748 
1749 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class I>
1750 inline typename std::enable_if<boost::multiprecision::detail::is_signed<I>::value && boost::multiprecision::detail::is_integral<I>::value>::type eval_ldexp(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg, I e)
1751 {
1752    if ((e > (std::numeric_limits<Exponent>::max)()) || (e < (std::numeric_limits<Exponent>::min)()))
1753    {
1754       res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend();
1755       if (e < 0)
1756          res.negate();
1757    }
1758    else
1759       eval_ldexp(res, arg, static_cast<Exponent>(e));
1760 }
1761 
1762 /*
1763 * Sign manipulation
1764 */
1765 
1766 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
1767    unsigned Digits2, digit_base_type DigitBase2, class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2>
1768 inline void eval_abs(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits2, DigitBase2, Allocator2, Exponent2, MinE2, MaxE2>& arg)
1769 {
1770    res        = arg;
1771    res.sign() = false;
1772 }
1773 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1774 inline void eval_abs(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1775 {
1776    res        = arg;
1777    res.sign() = false;
1778 }
1779 
1780 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
1781    unsigned Digits2, digit_base_type DigitBase2, class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2>
1782 inline void eval_fabs(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits2, DigitBase2, Allocator2, Exponent2, MinE2, MaxE2>& arg)
1783 {
1784    res        = arg;
1785    res.sign() = false;
1786 }
1787 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1788 inline void eval_fabs(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1789 {
1790    res        = arg;
1791    res.sign() = false;
1792 }
1793 
1794 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1795 inline int eval_fpclassify(const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1796 {
1797    switch (arg.exponent())
1798    {
1799    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1800       return FP_ZERO;
1801    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1802       return FP_INFINITE;
1803    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1804       return FP_NAN;
1805    }
1806    return FP_NORMAL;
1807 }
1808 
1809 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1810 inline void eval_sqrt(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1811 {
1812    using default_ops::eval_bit_test;
1813    using default_ops::eval_increment;
1814    using default_ops::eval_integer_sqrt;
1815    switch (arg.exponent())
1816    {
1817    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1818       errno = EDOM;
1819       // fallthrough...
1820    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1821       res = arg;
1822       return;
1823    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1824       if (arg.sign())
1825       {
1826          res   = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
1827          errno = EDOM;
1828       }
1829       else
1830          res = arg;
1831       return;
1832    }
1833    if (arg.sign())
1834    {
1835       res   = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
1836       errno = EDOM;
1837       return;
1838    }
1839 
1840    typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type t(arg.bits()), r, s;
1841    eval_left_shift(t, arg.exponent() & 1 ? cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count : cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1);
1842    eval_integer_sqrt(s, r, t);
1843 
1844    if (!eval_bit_test(s, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count))
1845    {
1846       // We have exactly the right number of cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count in the result, round as required:
1847       if (s.compare(r) < 0)
1848       {
1849          eval_increment(s);
1850       }
1851    }
1852    typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type ae = arg.exponent();
1853    res.exponent()                                                                               = ae / 2;
1854    res.sign() = false;
1855    if ((ae & 1) && (ae < 0))
1856       --res.exponent();
1857    copy_and_round(res, s);
1858 }
1859 
1860 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1861 inline void eval_floor(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1862 {
1863    using default_ops::eval_increment;
1864    switch (arg.exponent())
1865    {
1866    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1867       errno = EDOM;
1868       // fallthrough...
1869    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1870    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1871       res = arg;
1872       return;
1873    }
1874    using shift_type = typename std::conditional<sizeof(typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type) < sizeof(int), int, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type>::type;
1875    shift_type                                                                                                                                                                                                                                        shift =
1876        (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - arg.exponent() - 1;
1877    if ((arg.exponent() > (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent) || (shift <= 0))
1878    {
1879       // Either arg is already an integer, or a special value:
1880       res = arg;
1881       return;
1882    }
1883    if (shift >= (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)
1884    {
1885       res = static_cast<signed_limb_type>(arg.sign() ? -1 : 0);
1886       return;
1887    }
1888    bool fractional = (shift_type)eval_lsb(arg.bits()) < shift;
1889    res             = arg;
1890    eval_right_shift(res.bits(), static_cast<double_limb_type>(shift));
1891    if (fractional && res.sign())
1892    {
1893       eval_increment(res.bits());
1894 
1895       const std::ptrdiff_t shift_check =
1896          static_cast<std::ptrdiff_t>(static_cast<std::ptrdiff_t>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) - 1 - static_cast<std::ptrdiff_t>(shift));
1897 
1898       if (static_cast<std::ptrdiff_t>(eval_msb(res.bits())) != shift_check)
1899       {
1900          // Must have extended result by one bit in the increment:
1901          --shift;
1902          ++res.exponent();
1903       }
1904    }
1905    eval_left_shift(res.bits(), static_cast<double_limb_type>(shift));
1906 }
1907 
1908 template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1909 inline void eval_ceil(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1910 {
1911    using default_ops::eval_increment;
1912    switch (arg.exponent())
1913    {
1914    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1915       errno = EDOM;
1916       // fallthrough...
1917    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1918    case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1919       res = arg;
1920       return;
1921    }
1922    using shift_type = typename std::conditional<sizeof(typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type) < sizeof(int), int, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type>::type;
1923    shift_type                                                                                                                                                                                                                                        shift = (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - arg.exponent() - 1;
1924    if ((arg.exponent() > (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent) || (shift <= 0))
1925    {
1926       // Either arg is already an integer, or a special value:
1927       res = arg;
1928       return;
1929    }
1930    if (shift >= (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)
1931    {
1932       bool s     = arg.sign(); // takes care of signed zeros
1933       res        = static_cast<signed_limb_type>(arg.sign() ? 0 : 1);
1934       res.sign() = s;
1935       return;
1936    }
1937    bool fractional = (shift_type)eval_lsb(arg.bits()) < shift;
1938    res             = arg;
1939    eval_right_shift(res.bits(), shift);
1940    if (fractional && !res.sign())
1941    {
1942       eval_increment(res.bits());
1943       if ((std::ptrdiff_t)eval_msb(res.bits()) != cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 - shift)
1944       {
1945          // Must have extended result by one bit in the increment:
1946          --shift;
1947          ++res.exponent();
1948       }
1949    }
1950    eval_left_shift(res.bits(), shift);
1951 }
1952 
1953 template <unsigned D1, backends::digit_base_type B1, class A1, class E1, E1 M1, E1 M2>
1954 int eval_signbit(const cpp_bin_float<D1, B1, A1, E1, M1, M2>& val)
1955 {
1956    return val.sign();
1957 }
1958 
1959 template <unsigned D1, backends::digit_base_type B1, class A1, class E1, E1 M1, E1 M2>
1960 inline std::size_t hash_value(const cpp_bin_float<D1, B1, A1, E1, M1, M2>& val)
1961 {
1962    std::size_t result = hash_value(val.bits());
1963    boost::multiprecision::detail::hash_combine(result, val.exponent(), val.sign());
1964    return result;
1965 }
1966 
1967 } // namespace backends
1968 
1969 namespace detail {
1970 
1971 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinExponent, Exponent MaxExponent>
1972 struct transcendental_reduction_type<boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinExponent, MaxExponent> >
1973 {
1974    //
1975    // The type used for trigonometric reduction needs 3 times the precision of the base type.
1976    // This is double the precision of the original type, plus the largest exponent supported.
1977    // As a practical measure the largest argument supported is 1/eps, as supporting larger
1978    // arguments requires the division of argument by PI/2 to also be done at higher precision,
1979    // otherwise the result (an integer) can not be represented exactly.
1980    // 
1981    // See ARGUMENT REDUCTION FOR HUGE ARGUMENTS. K C Ng.
1982    //
1983    using type = boost::multiprecision::backends::cpp_bin_float<
1984        boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinExponent, MaxExponent>::bit_count * 3, 
1985        boost::multiprecision::backends::digit_base_2, 
1986        Allocator, Exponent, MinExponent, MaxExponent>;
1987 };
1988 #ifdef BOOST_HAS_INT128
1989 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinExponent, Exponent MaxExponent>
1990 struct is_convertible_arithmetic<int128_type, boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinExponent, MaxExponent> > : public std::true_type
1991 {};
1992 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinExponent, Exponent MaxExponent>
1993 struct is_convertible_arithmetic<uint128_type, boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinExponent, MaxExponent> > : public std::true_type
1994 {};
1995 #endif
1996 
1997 } // namespace detail
1998 
1999 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Exponent, Exponent MinE, Exponent MaxE, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
2000 inline boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates>
2001     copysign BOOST_PREVENT_MACRO_SUBSTITUTION(
2002         const boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates>& a,
2003         const boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates>& b)
2004 {
2005    boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> res(a);
2006    res.backend().sign() = b.backend().sign();
2007    return res;
2008 }
2009 
2010 template <unsigned Digits, backends::digit_base_type DigitBase, class Exponent, Exponent MinE, Exponent MaxE, class Allocator>
2011 struct number_category<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > : public std::integral_constant<int, boost::multiprecision::number_kind_floating_point>
2012 {};
2013 
2014 template <unsigned Digits, backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2>
2015 struct is_equivalent_number_type<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2> >
2016    : public std::integral_constant<bool, true> {};
2017 
2018 } // namespace multiprecision
2019 
2020 namespace math {
2021 
2022 using boost::multiprecision::copysign;
2023 using boost::multiprecision::signbit;
2024 
2025 } // namespace math
2026 
2027 } // namespace boost
2028 
2029 #include <boost/multiprecision/cpp_bin_float/io.hpp>
2030 #include <boost/multiprecision/cpp_bin_float/transcendental.hpp>
2031 
2032 namespace std {
2033 
2034 //
2035 // numeric_limits [partial] specializations for the types declared in this header:
2036 //
2037 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2038 class numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >
2039 {
2040    using number_type = boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates>;
2041 
2042  private:
2043     //
2044     // Functions to calculate cached values stored in static values:
2045     //
2046     static number_type get_min()
2047     {
2048        using ui_type = typename std::tuple_element<0, typename number_type::backend_type::unsigned_types>::type;
2049        number_type value(ui_type(1u));
2050        value.backend().exponent() = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent;
2051        return value;
2052     }
2053 #ifdef BOOST_MSVC
2054 #pragma warning(push)
2055 #pragma warning(disable : 4127) // conditional expression is constant
2056 #endif
2057     static number_type get_max()
2058     {
2059        number_type value;
2060        BOOST_IF_CONSTEXPR(std::is_void<Allocator>::value)
2061           eval_complement(value.backend().bits(), value.backend().bits());
2062        else
2063        {
2064           // We jump through hoops here using the backend type directly just to keep VC12 happy
2065           // (ie compiler workaround, for very strange compiler bug):
2066           using boost::multiprecision::default_ops::eval_add;
2067           using boost::multiprecision::default_ops::eval_decrement;
2068           using boost::multiprecision::default_ops::eval_left_shift;
2069           using int_backend_type = typename number_type::backend_type::rep_type;
2070           using ui_type = typename std::tuple_element<0, typename int_backend_type::unsigned_types>::type;
2071           int_backend_type                                                                    i;
2072           i = ui_type(1u);
2073           eval_left_shift(i, boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1);
2074           int_backend_type j(i);
2075           eval_decrement(i);
2076           eval_add(j, i);
2077           value.backend().bits() = j;
2078        }
2079        value.backend().exponent() = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent;
2080        return value;
2081     }
2082 #ifdef BOOST_MSVC
2083 #pragma warning(pop)
2084 #endif
2085     static number_type get_epsilon()
2086     {
2087        using ui_type = typename std::tuple_element<0, typename number_type::backend_type::unsigned_types>::type;
2088        number_type value(ui_type(1u));
2089        return ldexp(value, 1 - static_cast<int>(digits));
2090     }
2091     // What value should this be????
2092     static number_type get_round_error()
2093     {
2094        // returns 0.5
2095        return ldexp(number_type(1u), -1);
2096     }
2097     static number_type get_infinity()
2098     {
2099        number_type value;
2100        value.backend().exponent() = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
2101        return value;
2102     }
2103     static number_type get_quiet_NaN()
2104     {
2105        number_type value;
2106        value.backend().exponent() = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan;
2107        return value;
2108     }
2109 
2110  public:
2111    static constexpr bool is_specialized = true;
2112    static number_type(min)()
2113    {
2114       // C++11 thread safe static initialization:
2115       static number_type value = get_min();
2116       return value;
2117    }
2118    static number_type(max)()
2119    {
2120       // C++11 thread safe static initialization:
2121       static number_type value = get_max();
2122       return value;
2123    }
2124    static constexpr number_type lowest()
2125    {
2126       return -(max)();
2127    }
2128    static constexpr int digits   = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count;
2129    static constexpr int digits10 = boost::multiprecision::detail::calc_digits10<static_cast<unsigned>(digits)>::value;
2130    // Is this really correct???
2131    static constexpr int  max_digits10 = boost::multiprecision::detail::calc_max_digits10<static_cast<unsigned>(digits)>::value;
2132    static constexpr bool is_signed    = true;
2133    static constexpr bool is_integer   = false;
2134    static constexpr bool is_exact     = false;
2135    static constexpr int  radix        = 2;
2136    static number_type          epsilon()
2137    {
2138       // C++11 thread safe static initialization:
2139       static number_type value = get_epsilon();
2140       return value;
2141    }
2142    // What value should this be????
2143    static number_type round_error()
2144    {
2145       // returns 0.5
2146       // C++11 thread safe static initialization:
2147       static number_type value = get_round_error();
2148       return value;
2149    }
2150    static constexpr typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type min_exponent      = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent;
2151    static constexpr typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type min_exponent10    = (min_exponent / 1000) * 301L;
2152    static constexpr typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type max_exponent      = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent;
2153    static constexpr typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type max_exponent10    = (max_exponent / 1000) * 301L;
2154    static constexpr bool                                                                                                             has_infinity      = true;
2155    static constexpr bool                                                                                                             has_quiet_NaN     = true;
2156    static constexpr bool                                                                                                             has_signaling_NaN = false;
2157    static constexpr float_denorm_style has_denorm                                                                                                      = denorm_absent;
2158    static constexpr bool               has_denorm_loss                                                                                                 = false;
2159    static number_type infinity()
2160    {
2161       // C++11 thread safe static initialization:
2162       static number_type value = get_infinity();
2163       return value;
2164    }
2165    static number_type quiet_NaN()
2166    {
2167       // C++11 thread safe static initialization:
2168       static number_type value = get_quiet_NaN();
2169       return value;
2170    }
2171    static constexpr number_type signaling_NaN()
2172    {
2173       return number_type(0);
2174    }
2175    static constexpr number_type denorm_min() { return get_min(); }
2176    static constexpr bool        is_iec559         = false;
2177    static constexpr bool        is_bounded        = true;
2178    static constexpr bool        is_modulo         = false;
2179    static constexpr bool        traps             = true;
2180    static constexpr bool        tinyness_before   = false;
2181    static constexpr float_round_style round_style = round_to_nearest;
2182 };
2183 
2184 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2185 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::digits;
2186 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2187 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::digits10;
2188 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2189 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::max_digits10;
2190 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2191 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_signed;
2192 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2193 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_integer;
2194 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2195 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_exact;
2196 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2197 constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::radix;
2198 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2199 constexpr typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::min_exponent;
2200 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2201 constexpr typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::min_exponent10;
2202 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2203 constexpr typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::max_exponent;
2204 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2205 constexpr typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::max_exponent10;
2206 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2207 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::has_infinity;
2208 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2209 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::has_quiet_NaN;
2210 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2211 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::has_signaling_NaN;
2212 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2213 constexpr float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::has_denorm;
2214 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2215 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::has_denorm_loss;
2216 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2217 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_iec559;
2218 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2219 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_bounded;
2220 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2221 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_modulo;
2222 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2223 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::traps;
2224 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2225 constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::tinyness_before;
2226 template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2227 constexpr float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::round_style;
2228 
2229 
2230 } // namespace std
2231 
2232 #endif