Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/multiprecision/cpp_bin_float.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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