From b640732abd0ebeb99ff77aa3190b0a135e77110e Mon Sep 17 00:00:00 2001 From: John Maddock Date: Thu, 1 Nov 2012 19:01:08 +0000 Subject: [PATCH] Add additional template parameter to mpfr_float_backend to allow stack-based floats. [SVN r81135] --- .../boost_multiprecision/indexes/s01.html | 4 +- .../boost_multiprecision/indexes/s02.html | 4 +- .../boost_multiprecision/indexes/s03.html | 19 +- .../boost_multiprecision/indexes/s04.html | 14 +- doc/html/boost_multiprecision/map/hist.html | 4 + .../tut/floats/mpfr_float.html | 23 +- doc/html/index.html | 2 +- doc/multiprecision.qbk | 20 +- include/boost/multiprecision/mpfr.hpp | 802 ++++++++++++------ test/test_arithmetic.cpp | 1 + 10 files changed, 617 insertions(+), 276 deletions(-) diff --git a/doc/html/boost_multiprecision/indexes/s01.html b/doc/html/boost_multiprecision/indexes/s01.html index 680560fd..dcd3d39e 100644 --- a/doc/html/boost_multiprecision/indexes/s01.html +++ b/doc/html/boost_multiprecision/indexes/s01.html @@ -13,9 +13,9 @@
PrevUpHomeNext
-
+

-Function Index

+Function Index

A B C D E F I L M P R S T Z

diff --git a/doc/html/boost_multiprecision/indexes/s02.html b/doc/html/boost_multiprecision/indexes/s02.html index d15a40c9..41276154 100644 --- a/doc/html/boost_multiprecision/indexes/s02.html +++ b/doc/html/boost_multiprecision/indexes/s02.html @@ -13,9 +13,9 @@
PrevUpHomeNext
-
+

-Class Index

+Class Index

C E G I M N T

diff --git a/doc/html/boost_multiprecision/indexes/s03.html b/doc/html/boost_multiprecision/indexes/s03.html index 729668d3..bbdea96e 100644 --- a/doc/html/boost_multiprecision/indexes/s03.html +++ b/doc/html/boost_multiprecision/indexes/s03.html @@ -13,10 +13,10 @@
PrevUpHomeNext
-
+

-Typedef Index

-

C I L M T U

+Typedef Index
+

C I L M S T U

C @@ -198,6 +198,19 @@
+S +
+
+
T
    diff --git a/doc/html/boost_multiprecision/indexes/s04.html b/doc/html/boost_multiprecision/indexes/s04.html index adbddd56..9d0e47c3 100644 --- a/doc/html/boost_multiprecision/indexes/s04.html +++ b/doc/html/boost_multiprecision/indexes/s04.html @@ -12,9 +12,9 @@
    PrevUpHome
    -
    +

    -Index

    +Index

A B C D E F G I L M N O P R S T U Z

  • @@ -897,6 +899,14 @@
    • +

      static_mpfr_float_100

      + +
    • +
    • +

      static_mpfr_float_50

      + +
    • +
    • str

    • diff --git a/doc/html/boost_multiprecision/map/hist.html b/doc/html/boost_multiprecision/map/hist.html index 7c4b992f..eec38fe9 100644 --- a/doc/html/boost_multiprecision/map/hist.html +++ b/doc/html/boost_multiprecision/map/hist.html @@ -59,6 +59,10 @@ Refactored cpp_int_backend based on review comments with new template parameter structure. +
    • + Added additional template parameter to mpfr_float_backend + to allow stack-based allocation. +
    diff --git a/doc/html/boost_multiprecision/tut/floats/mpfr_float.html b/doc/html/boost_multiprecision/tut/floats/mpfr_float.html index 40126cf1..29355351 100644 --- a/doc/html/boost_multiprecision/tut/floats/mpfr_float.html +++ b/doc/html/boost_multiprecision/tut/floats/mpfr_float.html @@ -22,7 +22,13 @@

    namespace boost{ namespace multiprecision{
     
    -template <unsigned Digits10>
    +enum mpfr_allocation_type
    +{
    +   allocate_stack,
    +   allocate_dynamic
    +};
    +
    +template <unsigned Digits10, mpfr_allocation_type AllocateType = allocate_dynamic>
     class mpfr_float_backend;
     
     typedef number<mpfr_float_backend<50> >    mpfr_float_50;
    @@ -31,6 +37,9 @@
     typedef number<mpfr_float_backend<1000> >  mpfr_float_1000;
     typedef number<mpfr_float_backend<0> >     mpfr_float;
     
    +typedef number<mpfr_float_backend<50, allocate_stack> >    static_mpfr_float_50;
    +typedef number<mpfr_float_backend<100, allocate_stack> >   static_mpfr_float_100;
    +
     }} // namespaces
     

    @@ -51,6 +60,18 @@ whose precision can be controlled via the numbers member functions.

    +

    + In addition the second template parameter lets you choose between dynamic + allocation (the default, and uses MPFR's normal allocation routines), or + stack allocation (where all the memory required for the underlying data + types is stored within mpfr_float_backend). + The latter option can result in significantly faster code, at the expense + of growing the size of mpfr_float_backend. + It can only be used at fixed precision, and should only be used for lower + digit counts. Note that we can not guarentee that using allocate_stack + won't cause any calls to mpfr's allocation routines, as mpfr may call these + inside it's own code. +

    diff --git a/doc/html/index.html b/doc/html/index.html index 3373c51d..0c8517c2 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -124,7 +124,7 @@
    [Note]
    - +

    Last revised: November 01, 2012 at 11:12:34 GMT

    Last revised: November 01, 2012 at 18:56:42 GMT


    diff --git a/doc/multiprecision.qbk b/doc/multiprecision.qbk index d2ff465f..64829ae8 100644 --- a/doc/multiprecision.qbk +++ b/doc/multiprecision.qbk @@ -730,7 +730,13 @@ as a valid floating point number. namespace boost{ namespace multiprecision{ - template + enum mpfr_allocation_type + { + allocate_stack, + allocate_dynamic + }; + + template class mpfr_float_backend; typedef number > mpfr_float_50; @@ -739,6 +745,9 @@ as a valid floating point number. typedef number > mpfr_float_1000; typedef number > mpfr_float; + typedef number > static_mpfr_float_50; + typedef number > static_mpfr_float_100; + }} // namespaces The `mpfr_float_backend` type is used in conjunction with `number`: It acts as a thin wrapper around the [mpfr] `mpfr_t` @@ -751,6 +760,14 @@ mpfr_float_500, mpfr_float_1000 provide arithmetic types at 50, 100, 500 and 100 respectively. The typedef mpfr_float provides a variable precision type whose precision can be controlled via the `number`s member functions. +In addition the second template parameter lets you choose between dynamic allocation (the default, +and uses MPFR's normal allocation routines), +or stack allocation (where all the memory required for the underlying data types is stored +within `mpfr_float_backend`). The latter option can result in significantly faster code, at the +expense of growing the size of `mpfr_float_backend`. It can only be used at fixed precision, and +should only be used for lower digit counts. Note that we can not guarentee that using `allocate_stack` +won't cause any calls to mpfr's allocation routines, as mpfr may call these inside it's own code. + [note This type only provides `numeric_limits` support when the precision is fixed at compile time.] As well as the usual conversions from arithmetic and string types, instances of `number >` are @@ -2897,6 +2914,7 @@ Windows Vista machine. * Added support for fused-multiply-add/subtract with GMP support. * Tweaked expression template unpacking to use fewer temporaries when the LHS also appears in the RHS. * Refactored `cpp_int_backend` based on review comments with new template parameter structure. +* Added additional template parameter to `mpfr_float_backend` to allow stack-based allocation. [h4 Pre-review history] diff --git a/include/boost/multiprecision/mpfr.hpp b/include/boost/multiprecision/mpfr.hpp index ec3085c7..7924b414 100644 --- a/include/boost/multiprecision/mpfr.hpp +++ b/include/boost/multiprecision/mpfr.hpp @@ -17,17 +17,24 @@ #include #include -namespace boost{ +namespace boost{ namespace multiprecision{ + +enum mpfr_allocation_type +{ + allocate_stack, + allocate_dynamic +}; + namespace backends{ -template +template struct mpfr_float_backend; } // namespace backends -template -struct number_category > : public mpl::int_{}; +template +struct number_category > : public mpl::int_{}; namespace backends{ @@ -35,15 +42,25 @@ namespace detail{ inline long get_default_precision() { return 50; } +template +struct mpfr_float_imp; + template -struct mpfr_float_imp +struct mpfr_float_imp { typedef mpl::list signed_types; typedef mpl::list unsigned_types; typedef mpl::list float_types; typedef long exponent_type; - mpfr_float_imp() BOOST_NOEXCEPT {} + mpfr_float_imp() + { + mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); + } + mpfr_float_imp(unsigned prec) + { + mpfr_init2(m_data, prec); + } mpfr_float_imp(const mpfr_float_imp& o) { @@ -281,7 +298,8 @@ struct mpfr_float_imp BOOST_ASSERT(m_data[0]._mpfr_d); mpfr_neg(m_data, m_data, GMP_RNDN); } - int compare(const mpfr_float_backend& o)const BOOST_NOEXCEPT + template + int compare(const mpfr_float_backend& o)const BOOST_NOEXCEPT { BOOST_ASSERT(m_data[0]._mpfr_d && o.m_data[0]._mpfr_d); return mpfr_cmp(m_data, o.m_data); @@ -299,19 +317,19 @@ struct mpfr_float_imp template int compare(V v)const BOOST_NOEXCEPT { - mpfr_float_backend d; + mpfr_float_backend d; d = v; return compare(d); } - mpfr_t& data() BOOST_NOEXCEPT - { + mpfr_t& data() BOOST_NOEXCEPT + { BOOST_ASSERT(m_data[0]._mpfr_d); - return m_data; + return m_data; } - const mpfr_t& data()const BOOST_NOEXCEPT - { + const mpfr_t& data()const BOOST_NOEXCEPT + { BOOST_ASSERT(m_data[0]._mpfr_d); - return m_data; + return m_data; } protected: mpfr_t m_data; @@ -322,89 +340,344 @@ protected: } }; -} // namespace detail +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4127) // Conditional expression is constant +#endif template -struct mpfr_float_backend : public detail::mpfr_float_imp +struct mpfr_float_imp { - mpfr_float_backend() + typedef mpl::list signed_types; + typedef mpl::list unsigned_types; + typedef mpl::list float_types; + typedef long exponent_type; + + static const unsigned digits2 = (digits10 * 1000uL) / 301uL + ((digits10 * 1000uL) % 301 ? 2u : 1u); + static const unsigned limb_count = mpfr_custom_get_size(digits2) / sizeof(mp_limb_t); + + mpfr_float_imp() { - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); + mpfr_custom_init(m_buffer, digits2); + mpfr_custom_init_set(m_data, MPFR_NAN_KIND, 0, digits2, m_buffer); } - mpfr_float_backend(const mpfr_float_backend& o) : detail::mpfr_float_imp(o) {} + + mpfr_float_imp(const mpfr_float_imp& o) + { + mpfr_custom_init(m_buffer, digits2); + mpfr_custom_init_set(m_data, MPFR_NAN_KIND, 0, digits2, m_buffer); + mpfr_set(m_data, o.m_data, GMP_RNDN); + } + mpfr_float_imp& operator = (const mpfr_float_imp& o) BOOST_NOEXCEPT + { + mpfr_set(m_data, o.m_data, GMP_RNDN); + return *this; + } +#ifdef _MPFR_H_HAVE_INTMAX_T + mpfr_float_imp& operator = (unsigned long long i) BOOST_NOEXCEPT + { + mpfr_set_uj(m_data, i, GMP_RNDN); + return *this; + } + mpfr_float_imp& operator = (long long i) BOOST_NOEXCEPT + { + mpfr_set_sj(m_data, i, GMP_RNDN); + return *this; + } +#else + mpfr_float_imp& operator = (unsigned long long i) + { + unsigned long long mask = ((1uLL << std::numeric_limits::digits) - 1); + unsigned shift = 0; + mpfr_t t; + mp_limb_t t_limbs[limb_count]; + mpfr_custom_init(t_limbs, digits2); + mpfr_custom_init_set(t, MPFR_NAN_KIND, 0, digits2, t_limbs); + mpfr_set_ui(m_data, 0, GMP_RNDN); + while(i) + { + mpfr_set_ui(t, static_cast(i & mask), GMP_RNDN); + if(shift) + mpfr_mul_2exp(t, t, shift, GMP_RNDN); + mpfr_add(m_data, m_data, t, GMP_RNDN); + shift += std::numeric_limits::digits; + i >>= std::numeric_limits::digits; + } + return *this; + } + mpfr_float_imp& operator = (long long i) + { + BOOST_MP_USING_ABS + bool neg = i < 0; + *this = static_cast(abs(i)); + if(neg) + mpfr_neg(m_data, m_data, GMP_RNDN); + return *this; + } +#endif + mpfr_float_imp& operator = (unsigned long i) BOOST_NOEXCEPT + { + mpfr_set_ui(m_data, i, GMP_RNDN); + return *this; + } + mpfr_float_imp& operator = (long i) BOOST_NOEXCEPT + { + mpfr_set_si(m_data, i, GMP_RNDN); + return *this; + } + mpfr_float_imp& operator = (double d) BOOST_NOEXCEPT + { + mpfr_set_d(m_data, d, GMP_RNDN); + return *this; + } + mpfr_float_imp& operator = (long double a) BOOST_NOEXCEPT + { + mpfr_set_ld(m_data, a, GMP_RNDN); + return *this; + } + mpfr_float_imp& operator = (const char* s) + { + if(mpfr_set_str(m_data, s, 10, GMP_RNDN) != 0) + { + BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number."))); + } + return *this; + } + void swap(mpfr_float_imp& o) BOOST_NOEXCEPT + { + // We have to swap by copying: + mpfr_float_imp t(*this); + *this = o; + o = t; + } + std::string str(std::streamsize digits, std::ios_base::fmtflags f)const + { + BOOST_ASSERT(m_data[0]._mpfr_d); + + bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific; + bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed; + + std::streamsize org_digits(digits); + + if(scientific && digits) + ++digits; + + std::string result; + mp_exp_t e; + if(mpfr_inf_p(m_data)) + { + if(mpfr_sgn(m_data) < 0) + result = "-inf"; + else if(f & std::ios_base::showpos) + result = "+inf"; + else + result = "inf"; + return result; + } + if(mpfr_nan_p(m_data)) + { + result = "nan"; + return result; + } + if(mpfr_zero_p(m_data)) + { + e = 0; + result = "0"; + } + else + { + char* ps = mpfr_get_str (0, &e, 10, static_cast(digits), m_data, GMP_RNDN); + --e; // To match with what our formatter expects. + if(fixed && e != -1) + { + // Oops we actually need a different number of digits to what we asked for: + mpfr_free_str(ps); + digits += e + 1; + if(digits == 0) + { + // We need to get *all* the digits and then possibly round up, + // we end up with either "0" or "1" as the result. + ps = mpfr_get_str (0, &e, 10, 0, m_data, GMP_RNDN); + --e; + unsigned offset = *ps == '-' ? 1 : 0; + if(ps[offset] > '5') + { + ++e; + ps[offset] = '1'; + ps[offset + 1] = 0; + } + else if(ps[offset] == '5') + { + unsigned i = offset + 1; + bool round_up = false; + while(ps[i] != 0) + { + if(ps[i] != '0') + { + round_up = true; + break; + } + } + if(round_up) + { + ++e; + ps[offset] = '1'; + ps[offset + 1] = 0; + } + else + { + ps[offset] = '0'; + ps[offset + 1] = 0; + } + } + else + { + ps[offset] = '0'; + ps[offset + 1] = 0; + } + } + else if(digits > 0) + { + ps = mpfr_get_str (0, &e, 10, static_cast(digits), m_data, GMP_RNDN); + --e; // To match with what our formatter expects. + } + else + { + ps = mpfr_get_str (0, &e, 10, 1, m_data, GMP_RNDN); + --e; + unsigned offset = *ps == '-' ? 1 : 0; + ps[offset] = '0'; + ps[offset + 1] = 0; + } + } + result = ps ? ps : "0"; + if(ps) + mpfr_free_str(ps); + } + boost::multiprecision::detail::format_float_string(result, e, org_digits, f, 0 != mpfr_zero_p(m_data)); + return result; + } + void negate() BOOST_NOEXCEPT + { + mpfr_neg(m_data, m_data, GMP_RNDN); + } + template + int compare(const mpfr_float_backend& o)const BOOST_NOEXCEPT + { + return mpfr_cmp(m_data, o.m_data); + } + int compare(long i)const BOOST_NOEXCEPT + { + return mpfr_cmp_si(m_data, i); + } + int compare(unsigned long i)const BOOST_NOEXCEPT + { + return mpfr_cmp_ui(m_data, i); + } + template + int compare(V v)const BOOST_NOEXCEPT + { + mpfr_float_backend d; + d = v; + return compare(d); + } + mpfr_t& data() BOOST_NOEXCEPT + { + return m_data; + } + const mpfr_t& data()const BOOST_NOEXCEPT + { + return m_data; + } +protected: + mpfr_t m_data; + mp_limb_t m_buffer[limb_count]; +}; + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +} // namespace detail + +template +struct mpfr_float_backend : public detail::mpfr_float_imp +{ + mpfr_float_backend() : detail::mpfr_float_imp() {} + mpfr_float_backend(const mpfr_float_backend& o) : detail::mpfr_float_imp(o) {} #ifndef BOOST_NO_RVALUE_REFERENCES - mpfr_float_backend(mpfr_float_backend&& o) : detail::mpfr_float_imp(static_cast&&>(o)) {} + mpfr_float_backend(mpfr_float_backend&& o) : detail::mpfr_float_imp(static_cast&&>(o)) {} #endif template mpfr_float_backend(const mpfr_float_backend& val, typename enable_if_c::type* = 0) + : detail::mpfr_float_imp() { - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); mpfr_set(this->m_data, val.data(), GMP_RNDN); } template explicit mpfr_float_backend(const mpfr_float_backend& val, typename disable_if_c::type* = 0) + : detail::mpfr_float_imp() { - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); mpfr_set(this->m_data, val.data(), GMP_RNDN); } template mpfr_float_backend(const gmp_float& val, typename enable_if_c::type* = 0) + : detail::mpfr_float_imp() { - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); mpfr_set_f(this->m_data, val.data(), GMP_RNDN); } template mpfr_float_backend(const gmp_float& val, typename disable_if_c::type* = 0) + : detail::mpfr_float_imp() { - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); mpfr_set_f(this->m_data, val.data(), GMP_RNDN); } mpfr_float_backend(const gmp_int& val) + : detail::mpfr_float_imp() { - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); mpfr_set_z(this->m_data, val.data(), GMP_RNDN); } mpfr_float_backend(const gmp_rational& val) + : detail::mpfr_float_imp() { - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); mpfr_set_q(this->m_data, val.data(), GMP_RNDN); } mpfr_float_backend(const mpfr_t val) + : detail::mpfr_float_imp() { - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); mpfr_set(this->m_data, val, GMP_RNDN); } mpfr_float_backend(const mpf_t val) + : detail::mpfr_float_imp() { - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); mpfr_set_f(this->m_data, val, GMP_RNDN); } mpfr_float_backend(const mpz_t val) + : detail::mpfr_float_imp() { - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); mpfr_set_z(this->m_data, val, GMP_RNDN); } mpfr_float_backend(const mpq_t val) + : detail::mpfr_float_imp() { - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); mpfr_set_q(this->m_data, val, GMP_RNDN); } mpfr_float_backend& operator=(const mpfr_float_backend& o) { - *static_cast*>(this) = static_cast const&>(o); + *static_cast*>(this) = static_cast const&>(o); return *this; } #ifndef BOOST_NO_RVALUE_REFERENCES mpfr_float_backend& operator=(mpfr_float_backend&& o) BOOST_NOEXCEPT { - *static_cast*>(this) = static_cast&&>(o); + *static_cast*>(this) = static_cast&&>(o); return *this; } #endif template mpfr_float_backend& operator=(const V& v) { - *static_cast*>(this) = v; + *static_cast*>(this) = v; return *this; } mpfr_float_backend& operator=(const mpfr_t val)BOOST_NOEXCEPT @@ -453,80 +726,78 @@ struct mpfr_float_backend : public detail::mpfr_float_imp }; template <> -struct mpfr_float_backend<0> : public detail::mpfr_float_imp<0> +struct mpfr_float_backend<0, allocate_dynamic> : public detail::mpfr_float_imp<0, allocate_dynamic> { - mpfr_float_backend() - { - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision())); - } + mpfr_float_backend() : detail::mpfr_float_imp<0, allocate_dynamic>() {} mpfr_float_backend(const mpfr_t val) + : detail::mpfr_float_imp<0, allocate_dynamic>(mpfr_get_prec(val)) { - mpfr_init2(this->m_data, mpfr_get_prec(val)); mpfr_set(this->m_data, val, GMP_RNDN); } mpfr_float_backend(const mpf_t val) + : detail::mpfr_float_imp<0, allocate_dynamic>(mpf_get_prec(val)) { - mpfr_init2(this->m_data, mpf_get_prec(val)); mpfr_set_f(this->m_data, val, GMP_RNDN); } mpfr_float_backend(const mpz_t val) + : detail::mpfr_float_imp<0, allocate_dynamic>() { - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision())); mpfr_set_z(this->m_data, val, GMP_RNDN); } mpfr_float_backend(const mpq_t val) + : detail::mpfr_float_imp<0, allocate_dynamic>() { - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision())); mpfr_set_q(this->m_data, val, GMP_RNDN); } - mpfr_float_backend(const mpfr_float_backend& o) : detail::mpfr_float_imp<0>(o) {} + mpfr_float_backend(const mpfr_float_backend& o) : detail::mpfr_float_imp<0, allocate_dynamic>(o) {} #ifndef BOOST_NO_RVALUE_REFERENCES - mpfr_float_backend(mpfr_float_backend&& o) BOOST_NOEXCEPT : detail::mpfr_float_imp<0>(static_cast&&>(o)) {} + mpfr_float_backend(mpfr_float_backend&& o) BOOST_NOEXCEPT : detail::mpfr_float_imp<0, allocate_dynamic>(static_cast&&>(o)) {} #endif - mpfr_float_backend(const mpfr_float_backend& o, unsigned digits10) + mpfr_float_backend(const mpfr_float_backend& o, unsigned digits10) + : detail::mpfr_float_imp<0, allocate_dynamic>(digits10) { - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10)); *this = o; } template mpfr_float_backend(const mpfr_float_backend& val) + : detail::mpfr_float_imp<0, allocate_dynamic>(mpfr_get_prec(val.data())) { - mpfr_init2(this->m_data, mpfr_get_prec(val.data())); mpfr_set(this->m_data, val.data(), GMP_RNDN); } template mpfr_float_backend(const gmp_float& val) + : detail::mpfr_float_imp<0, allocate_dynamic>(mpf_get_prec(val.data())) { - mpfr_init2(this->m_data, mpf_get_prec(val.data())); mpfr_set_f(this->m_data, val.data(), GMP_RNDN); } mpfr_float_backend(const gmp_int& val) + : detail::mpfr_float_imp<0, allocate_dynamic>() { - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision())); mpfr_set_z(this->m_data, val.data(), GMP_RNDN); } mpfr_float_backend(const gmp_rational& val) + : detail::mpfr_float_imp<0, allocate_dynamic>() { - mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision())); mpfr_set_q(this->m_data, val.data(), GMP_RNDN); } mpfr_float_backend& operator=(const mpfr_float_backend& o) { - *static_cast*>(this) = static_cast const&>(o); + mpfr_set_prec(this->m_data, mpfr_get_prec(o.data())); + mpfr_set(this->m_data, o.data(), GMP_RNDN); return *this; } #ifndef BOOST_NO_RVALUE_REFERENCES mpfr_float_backend& operator=(mpfr_float_backend&& o) BOOST_NOEXCEPT { - *static_cast*>(this) = static_cast &&>(o); + *static_cast*>(this) = static_cast &&>(o); return *this; } #endif template mpfr_float_backend& operator=(const V& v) { - *static_cast*>(this) = v; + *static_cast*>(this) = v; return *this; } mpfr_float_backend& operator=(const mpfr_t val) BOOST_NOEXCEPT @@ -593,87 +864,87 @@ struct mpfr_float_backend<0> : public detail::mpfr_float_imp<0> } }; -template -inline typename enable_if, bool>::type eval_eq(const mpfr_float_backend& a, const T& b) BOOST_NOEXCEPT +template +inline typename enable_if, bool>::type eval_eq(const mpfr_float_backend& a, const T& b) BOOST_NOEXCEPT { return a.compare(b) == 0; } -template -inline typename enable_if, bool>::type eval_lt(const mpfr_float_backend& a, const T& b) BOOST_NOEXCEPT +template +inline typename enable_if, bool>::type eval_lt(const mpfr_float_backend& a, const T& b) BOOST_NOEXCEPT { return a.compare(b) < 0; } -template -inline typename enable_if, bool>::type eval_gt(const mpfr_float_backend& a, const T& b) BOOST_NOEXCEPT +template +inline typename enable_if, bool>::type eval_gt(const mpfr_float_backend& a, const T& b) BOOST_NOEXCEPT { return a.compare(b) > 0; } -template -inline void eval_add(mpfr_float_backend& result, const mpfr_float_backend& o) BOOST_NOEXCEPT +template +inline void eval_add(mpfr_float_backend& result, const mpfr_float_backend& o) BOOST_NOEXCEPT { mpfr_add(result.data(), result.data(), o.data(), GMP_RNDN); } -template -inline void eval_subtract(mpfr_float_backend& result, const mpfr_float_backend& o) BOOST_NOEXCEPT +template +inline void eval_subtract(mpfr_float_backend& result, const mpfr_float_backend& o) BOOST_NOEXCEPT { mpfr_sub(result.data(), result.data(), o.data(), GMP_RNDN); } -template -inline void eval_multiply(mpfr_float_backend& result, const mpfr_float_backend& o) BOOST_NOEXCEPT +template +inline void eval_multiply(mpfr_float_backend& result, const mpfr_float_backend& o) BOOST_NOEXCEPT { mpfr_mul(result.data(), result.data(), o.data(), GMP_RNDN); } -template -inline void eval_divide(mpfr_float_backend& result, const mpfr_float_backend& o) +template +inline void eval_divide(mpfr_float_backend& result, const mpfr_float_backend& o) { mpfr_div(result.data(), result.data(), o.data(), GMP_RNDN); } -template -inline void eval_add(mpfr_float_backend& result, unsigned long i) BOOST_NOEXCEPT +template +inline void eval_add(mpfr_float_backend& result, unsigned long i) BOOST_NOEXCEPT { mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN); } -template -inline void eval_subtract(mpfr_float_backend& result, unsigned long i) BOOST_NOEXCEPT +template +inline void eval_subtract(mpfr_float_backend& result, unsigned long i) BOOST_NOEXCEPT { mpfr_sub_ui(result.data(), result.data(), i, GMP_RNDN); } -template -inline void eval_multiply(mpfr_float_backend& result, unsigned long i) BOOST_NOEXCEPT +template +inline void eval_multiply(mpfr_float_backend& result, unsigned long i) BOOST_NOEXCEPT { mpfr_mul_ui(result.data(), result.data(), i, GMP_RNDN); } -template -inline void eval_divide(mpfr_float_backend& result, unsigned long i) +template +inline void eval_divide(mpfr_float_backend& result, unsigned long i) { mpfr_div_ui(result.data(), result.data(), i, GMP_RNDN); } -template -inline void eval_add(mpfr_float_backend& result, long i) BOOST_NOEXCEPT +template +inline void eval_add(mpfr_float_backend& result, long i) BOOST_NOEXCEPT { if(i > 0) mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN); else mpfr_sub_ui(result.data(), result.data(), std::abs(i), GMP_RNDN); } -template -inline void eval_subtract(mpfr_float_backend& result, long i) BOOST_NOEXCEPT +template +inline void eval_subtract(mpfr_float_backend& result, long i) BOOST_NOEXCEPT { if(i > 0) mpfr_sub_ui(result.data(), result.data(), i, GMP_RNDN); else mpfr_add_ui(result.data(), result.data(), std::abs(i), GMP_RNDN); } -template -inline void eval_multiply(mpfr_float_backend& result, long i) BOOST_NOEXCEPT +template +inline void eval_multiply(mpfr_float_backend& result, long i) BOOST_NOEXCEPT { mpfr_mul_ui(result.data(), result.data(), std::abs(i), GMP_RNDN); if(i < 0) mpfr_neg(result.data(), result.data(), GMP_RNDN); } -template -inline void eval_divide(mpfr_float_backend& result, long i) +template +inline void eval_divide(mpfr_float_backend& result, long i) { mpfr_div_ui(result.data(), result.data(), std::abs(i), GMP_RNDN); if(i < 0) @@ -682,31 +953,31 @@ inline void eval_divide(mpfr_float_backend& result, long i) // // Specialised 3 arg versions of the basic operators: // -template -inline void eval_add(mpfr_float_backend& a, const mpfr_float_backend& x, const mpfr_float_backend& y) BOOST_NOEXCEPT +template +inline void eval_add(mpfr_float_backend& a, const mpfr_float_backend& x, const mpfr_float_backend& y) BOOST_NOEXCEPT { mpfr_add(a.data(), x.data(), y.data(), GMP_RNDN); } -template -inline void eval_add(mpfr_float_backend& a, const mpfr_float_backend& x, unsigned long y) BOOST_NOEXCEPT +template +inline void eval_add(mpfr_float_backend& a, const mpfr_float_backend& x, unsigned long y) BOOST_NOEXCEPT { mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN); } -template -inline void eval_add(mpfr_float_backend& a, const mpfr_float_backend& x, long y) BOOST_NOEXCEPT +template +inline void eval_add(mpfr_float_backend& a, const mpfr_float_backend& x, long y) BOOST_NOEXCEPT { if(y < 0) mpfr_sub_ui(a.data(), x.data(), -y, GMP_RNDN); else mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN); } -template -inline void eval_add(mpfr_float_backend& a, unsigned long x, const mpfr_float_backend& y) BOOST_NOEXCEPT +template +inline void eval_add(mpfr_float_backend& a, unsigned long x, const mpfr_float_backend& y) BOOST_NOEXCEPT { mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN); } -template -inline void eval_add(mpfr_float_backend& a, long x, const mpfr_float_backend& y) BOOST_NOEXCEPT +template +inline void eval_add(mpfr_float_backend& a, long x, const mpfr_float_backend& y) BOOST_NOEXCEPT { if(x < 0) { @@ -716,31 +987,31 @@ inline void eval_add(mpfr_float_backend& a, long x, const mpfr_float_backend else mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN); } -template -inline void eval_subtract(mpfr_float_backend& a, const mpfr_float_backend& x, const mpfr_float_backend& y) BOOST_NOEXCEPT +template +inline void eval_subtract(mpfr_float_backend& a, const mpfr_float_backend& x, const mpfr_float_backend& y) BOOST_NOEXCEPT { mpfr_sub(a.data(), x.data(), y.data(), GMP_RNDN); } -template -inline void eval_subtract(mpfr_float_backend& a, const mpfr_float_backend& x, unsigned long y) BOOST_NOEXCEPT +template +inline void eval_subtract(mpfr_float_backend& a, const mpfr_float_backend& x, unsigned long y) BOOST_NOEXCEPT { mpfr_sub_ui(a.data(), x.data(), y, GMP_RNDN); } -template -inline void eval_subtract(mpfr_float_backend& a, const mpfr_float_backend& x, long y) BOOST_NOEXCEPT +template +inline void eval_subtract(mpfr_float_backend& a, const mpfr_float_backend& x, long y) BOOST_NOEXCEPT { if(y < 0) mpfr_add_ui(a.data(), x.data(), -y, GMP_RNDN); else mpfr_sub_ui(a.data(), x.data(), y, GMP_RNDN); } -template -inline void eval_subtract(mpfr_float_backend& a, unsigned long x, const mpfr_float_backend& y) BOOST_NOEXCEPT +template +inline void eval_subtract(mpfr_float_backend& a, unsigned long x, const mpfr_float_backend& y) BOOST_NOEXCEPT { mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN); } -template -inline void eval_subtract(mpfr_float_backend& a, long x, const mpfr_float_backend& y) BOOST_NOEXCEPT +template +inline void eval_subtract(mpfr_float_backend& a, long x, const mpfr_float_backend& y) BOOST_NOEXCEPT { if(x < 0) { @@ -751,18 +1022,18 @@ inline void eval_subtract(mpfr_float_backend& a, long x, const mpfr_float_ba mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN); } -template -inline void eval_multiply(mpfr_float_backend& a, const mpfr_float_backend& x, const mpfr_float_backend& y) BOOST_NOEXCEPT +template +inline void eval_multiply(mpfr_float_backend& a, const mpfr_float_backend& x, const mpfr_float_backend& y) BOOST_NOEXCEPT { mpfr_mul(a.data(), x.data(), y.data(), GMP_RNDN); } -template -inline void eval_multiply(mpfr_float_backend& a, const mpfr_float_backend& x, unsigned long y) BOOST_NOEXCEPT +template +inline void eval_multiply(mpfr_float_backend& a, const mpfr_float_backend& x, unsigned long y) BOOST_NOEXCEPT { mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN); } -template -inline void eval_multiply(mpfr_float_backend& a, const mpfr_float_backend& x, long y) BOOST_NOEXCEPT +template +inline void eval_multiply(mpfr_float_backend& a, const mpfr_float_backend& x, long y) BOOST_NOEXCEPT { if(y < 0) { @@ -772,13 +1043,13 @@ inline void eval_multiply(mpfr_float_backend& a, const mpfr_float_backend -inline void eval_multiply(mpfr_float_backend& a, unsigned long x, const mpfr_float_backend& y) BOOST_NOEXCEPT +template +inline void eval_multiply(mpfr_float_backend& a, unsigned long x, const mpfr_float_backend& y) BOOST_NOEXCEPT { mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN); } -template -inline void eval_multiply(mpfr_float_backend& a, long x, const mpfr_float_backend& y) BOOST_NOEXCEPT +template +inline void eval_multiply(mpfr_float_backend& a, long x, const mpfr_float_backend& y) BOOST_NOEXCEPT { if(x < 0) { @@ -789,18 +1060,18 @@ inline void eval_multiply(mpfr_float_backend& a, long x, const mpfr_float_ba mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN); } -template -inline void eval_divide(mpfr_float_backend& a, const mpfr_float_backend& x, const mpfr_float_backend& y) +template +inline void eval_divide(mpfr_float_backend& a, const mpfr_float_backend& x, const mpfr_float_backend& y) { mpfr_div(a.data(), x.data(), y.data(), GMP_RNDN); } -template -inline void eval_divide(mpfr_float_backend& a, const mpfr_float_backend& x, unsigned long y) +template +inline void eval_divide(mpfr_float_backend& a, const mpfr_float_backend& x, unsigned long y) { mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN); } -template -inline void eval_divide(mpfr_float_backend& a, const mpfr_float_backend& x, long y) +template +inline void eval_divide(mpfr_float_backend& a, const mpfr_float_backend& x, long y) { if(y < 0) { @@ -810,13 +1081,13 @@ inline void eval_divide(mpfr_float_backend& a, const mpfr_float_backend& else mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN); } -template -inline void eval_divide(mpfr_float_backend& a, unsigned long x, const mpfr_float_backend& y) +template +inline void eval_divide(mpfr_float_backend& a, unsigned long x, const mpfr_float_backend& y) { mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN); } -template -inline void eval_divide(mpfr_float_backend& a, long x, const mpfr_float_backend& y) +template +inline void eval_divide(mpfr_float_backend& a, long x, const mpfr_float_backend& y) { if(x < 0) { @@ -827,19 +1098,19 @@ inline void eval_divide(mpfr_float_backend& a, long x, const mpfr_float_back mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN); } -template -inline bool eval_is_zero(const mpfr_float_backend& val) BOOST_NOEXCEPT +template +inline bool eval_is_zero(const mpfr_float_backend& val) BOOST_NOEXCEPT { return 0 != mpfr_zero_p(val.data()); } -template -inline int eval_get_sign(const mpfr_float_backend& val) BOOST_NOEXCEPT +template +inline int eval_get_sign(const mpfr_float_backend& val) BOOST_NOEXCEPT { return mpfr_sgn(val.data()); } -template -inline void eval_convert_to(unsigned long* result, const mpfr_float_backend& val) +template +inline void eval_convert_to(unsigned long* result, const mpfr_float_backend& val) { if(mpfr_nan_p(val.data())) { @@ -847,8 +1118,8 @@ inline void eval_convert_to(unsigned long* result, const mpfr_float_backend -inline void eval_convert_to(long* result, const mpfr_float_backend& val) +template +inline void eval_convert_to(long* result, const mpfr_float_backend& val) { if(mpfr_nan_p(val.data())) { @@ -857,8 +1128,8 @@ inline void eval_convert_to(long* result, const mpfr_float_backend& va *result = mpfr_get_si(val.data(), GMP_RNDN); } #ifdef _MPFR_H_HAVE_INTMAX_T -template -inline void eval_convert_to(unsigned long long* result, const mpfr_float_backend& val) +template +inline void eval_convert_to(unsigned long long* result, const mpfr_float_backend& val) { if(mpfr_nan_p(val.data())) { @@ -866,8 +1137,8 @@ inline void eval_convert_to(unsigned long long* result, const mpfr_float_backend } *result = mpfr_get_uj(val.data(), GMP_RNDN); } -template -inline void eval_convert_to(long long* result, const mpfr_float_backend& val) +template +inline void eval_convert_to(long long* result, const mpfr_float_backend& val) { if(mpfr_nan_p(val.data())) { @@ -876,13 +1147,13 @@ inline void eval_convert_to(long long* result, const mpfr_float_backend -inline void eval_convert_to(double* result, const mpfr_float_backend& val) BOOST_NOEXCEPT +template +inline void eval_convert_to(double* result, const mpfr_float_backend& val) BOOST_NOEXCEPT { *result = mpfr_get_d(val.data(), GMP_RNDN); } -template -inline void eval_convert_to(long double* result, const mpfr_float_backend& val) BOOST_NOEXCEPT +template +inline void eval_convert_to(long double* result, const mpfr_float_backend& val) BOOST_NOEXCEPT { *result = mpfr_get_ld(val.data(), GMP_RNDN); } @@ -890,45 +1161,45 @@ inline void eval_convert_to(long double* result, const mpfr_float_backend -inline void eval_sqrt(mpfr_float_backend& result, const mpfr_float_backend& val) BOOST_NOEXCEPT +template +inline void eval_sqrt(mpfr_float_backend& result, const mpfr_float_backend& val) BOOST_NOEXCEPT { mpfr_sqrt(result.data(), val.data(), GMP_RNDN); } -template -inline void eval_abs(mpfr_float_backend& result, const mpfr_float_backend& val) BOOST_NOEXCEPT +template +inline void eval_abs(mpfr_float_backend& result, const mpfr_float_backend& val) BOOST_NOEXCEPT { mpfr_abs(result.data(), val.data(), GMP_RNDN); } -template -inline void eval_fabs(mpfr_float_backend& result, const mpfr_float_backend& val) BOOST_NOEXCEPT +template +inline void eval_fabs(mpfr_float_backend& result, const mpfr_float_backend& val) BOOST_NOEXCEPT { mpfr_abs(result.data(), val.data(), GMP_RNDN); } -template -inline void eval_ceil(mpfr_float_backend& result, const mpfr_float_backend& val) BOOST_NOEXCEPT +template +inline void eval_ceil(mpfr_float_backend& result, const mpfr_float_backend& val) BOOST_NOEXCEPT { mpfr_ceil(result.data(), val.data()); } -template -inline void eval_floor(mpfr_float_backend& result, const mpfr_float_backend& val) BOOST_NOEXCEPT +template +inline void eval_floor(mpfr_float_backend& result, const mpfr_float_backend& val) BOOST_NOEXCEPT { mpfr_floor(result.data(), val.data()); } -template -inline void eval_trunc(mpfr_float_backend& result, const mpfr_float_backend& val) +template +inline void eval_trunc(mpfr_float_backend& result, const mpfr_float_backend& val) { if(0 == mpfr_number_p(val.data())) { - result = boost::math::policies::raise_rounding_error("boost::multiprecision::trunc<%1%>(%1%)", 0, number >(val), 0, boost::math::policies::policy<>()).backend(); + result = boost::math::policies::raise_rounding_error("boost::multiprecision::trunc<%1%>(%1%)", 0, number >(val), 0, boost::math::policies::policy<>()).backend(); return; } mpfr_trunc(result.data(), val.data()); } -template -inline void eval_ldexp(mpfr_float_backend& result, const mpfr_float_backend& val, long e) BOOST_NOEXCEPT +template +inline void eval_ldexp(mpfr_float_backend& result, const mpfr_float_backend& val, long e) BOOST_NOEXCEPT { if(e > 0) mpfr_mul_2exp(result.data(), val.data(), e, GMP_RNDN); @@ -937,29 +1208,29 @@ inline void eval_ldexp(mpfr_float_backend& result, const mpfr_float_ba else result = val; } -template -inline void eval_frexp(mpfr_float_backend& result, const mpfr_float_backend& val, int* e) BOOST_NOEXCEPT +template +inline void eval_frexp(mpfr_float_backend& result, const mpfr_float_backend& val, int* e) BOOST_NOEXCEPT { long v; mpfr_get_d_2exp(&v, val.data(), GMP_RNDN); *e = v; eval_ldexp(result, val, -v); } -template -inline void eval_frexp(mpfr_float_backend& result, const mpfr_float_backend& val, long* e) BOOST_NOEXCEPT +template +inline void eval_frexp(mpfr_float_backend& result, const mpfr_float_backend& val, long* e) BOOST_NOEXCEPT { mpfr_get_d_2exp(e, val.data(), GMP_RNDN); return eval_ldexp(result, val, -*e); } -template -inline int eval_fpclassify(const mpfr_float_backend& val) BOOST_NOEXCEPT +template +inline int eval_fpclassify(const mpfr_float_backend& val) BOOST_NOEXCEPT { return mpfr_inf_p(val.data()) ? FP_INFINITE : mpfr_nan_p(val.data()) ? FP_NAN : mpfr_zero_p(val.data()) ? FP_ZERO : FP_NORMAL; } -template -inline void eval_pow(mpfr_float_backend& result, const mpfr_float_backend& b, const mpfr_float_backend& e) BOOST_NOEXCEPT +template +inline void eval_pow(mpfr_float_backend& result, const mpfr_float_backend& b, const mpfr_float_backend& e) BOOST_NOEXCEPT { mpfr_pow(result.data(), b.data(), e.data(), GMP_RNDN); } @@ -970,99 +1241,99 @@ inline void eval_pow(mpfr_float_backend& result, const mpfr_float_back // certain other enable_if usages are defined first. It's a capricious // and rather annoying compiler bug in other words.... // -# define BOOST_MP_ENABLE_IF_WORKAROUND (Digits10 || !Digits10) && +# define BOOST_MP_ENABLE_IF_WORKAROUND (Digits10 || !Digits10) && #else #define BOOST_MP_ENABLE_IF_WORKAROUND #endif -template -inline typename enable_if, mpl::bool_ > >::type eval_pow(mpfr_float_backend& result, const mpfr_float_backend& b, const Integer& e) BOOST_NOEXCEPT +template +inline typename enable_if, mpl::bool_ > >::type eval_pow(mpfr_float_backend& result, const mpfr_float_backend& b, const Integer& e) BOOST_NOEXCEPT { mpfr_pow_si(result.data(), b.data(), e, GMP_RNDN); } -template -inline typename enable_if, mpl::bool_ > >::type eval_pow(mpfr_float_backend& result, const mpfr_float_backend& b, const Integer& e) BOOST_NOEXCEPT +template +inline typename enable_if, mpl::bool_ > >::type eval_pow(mpfr_float_backend& result, const mpfr_float_backend& b, const Integer& e) BOOST_NOEXCEPT { mpfr_pow_ui(result.data(), b.data(), e, GMP_RNDN); } #undef BOOST_MP_ENABLE_IF_WORKAROUND -template -inline void eval_exp(mpfr_float_backend& result, const mpfr_float_backend& arg) BOOST_NOEXCEPT +template +inline void eval_exp(mpfr_float_backend& result, const mpfr_float_backend& arg) BOOST_NOEXCEPT { mpfr_exp(result.data(), arg.data(), GMP_RNDN); } -template -inline void eval_log(mpfr_float_backend& result, const mpfr_float_backend& arg) BOOST_NOEXCEPT +template +inline void eval_log(mpfr_float_backend& result, const mpfr_float_backend& arg) BOOST_NOEXCEPT { mpfr_log(result.data(), arg.data(), GMP_RNDN); } -template -inline void eval_log10(mpfr_float_backend& result, const mpfr_float_backend& arg) BOOST_NOEXCEPT +template +inline void eval_log10(mpfr_float_backend& result, const mpfr_float_backend& arg) BOOST_NOEXCEPT { mpfr_log10(result.data(), arg.data(), GMP_RNDN); } -template -inline void eval_sin(mpfr_float_backend& result, const mpfr_float_backend& arg) BOOST_NOEXCEPT +template +inline void eval_sin(mpfr_float_backend& result, const mpfr_float_backend& arg) BOOST_NOEXCEPT { mpfr_sin(result.data(), arg.data(), GMP_RNDN); } -template -inline void eval_cos(mpfr_float_backend& result, const mpfr_float_backend& arg) BOOST_NOEXCEPT +template +inline void eval_cos(mpfr_float_backend& result, const mpfr_float_backend& arg) BOOST_NOEXCEPT { mpfr_cos(result.data(), arg.data(), GMP_RNDN); } -template -inline void eval_tan(mpfr_float_backend& result, const mpfr_float_backend& arg) BOOST_NOEXCEPT +template +inline void eval_tan(mpfr_float_backend& result, const mpfr_float_backend& arg) BOOST_NOEXCEPT { mpfr_tan(result.data(), arg.data(), GMP_RNDN); } -template -inline void eval_asin(mpfr_float_backend& result, const mpfr_float_backend& arg) BOOST_NOEXCEPT +template +inline void eval_asin(mpfr_float_backend& result, const mpfr_float_backend& arg) BOOST_NOEXCEPT { mpfr_asin(result.data(), arg.data(), GMP_RNDN); } -template -inline void eval_acos(mpfr_float_backend& result, const mpfr_float_backend& arg) BOOST_NOEXCEPT +template +inline void eval_acos(mpfr_float_backend& result, const mpfr_float_backend& arg) BOOST_NOEXCEPT { mpfr_acos(result.data(), arg.data(), GMP_RNDN); } -template -inline void eval_atan(mpfr_float_backend& result, const mpfr_float_backend& arg) BOOST_NOEXCEPT +template +inline void eval_atan(mpfr_float_backend& result, const mpfr_float_backend& arg) BOOST_NOEXCEPT { mpfr_atan(result.data(), arg.data(), GMP_RNDN); } -template -inline void eval_atan2(mpfr_float_backend& result, const mpfr_float_backend& arg1, const mpfr_float_backend& arg2) BOOST_NOEXCEPT +template +inline void eval_atan2(mpfr_float_backend& result, const mpfr_float_backend& arg1, const mpfr_float_backend& arg2) BOOST_NOEXCEPT { mpfr_atan2(result.data(), arg1.data(), arg2.data(), GMP_RNDN); } -template -inline void eval_sinh(mpfr_float_backend& result, const mpfr_float_backend& arg) BOOST_NOEXCEPT +template +inline void eval_sinh(mpfr_float_backend& result, const mpfr_float_backend& arg) BOOST_NOEXCEPT { mpfr_sinh(result.data(), arg.data(), GMP_RNDN); } -template -inline void eval_cosh(mpfr_float_backend& result, const mpfr_float_backend& arg) BOOST_NOEXCEPT +template +inline void eval_cosh(mpfr_float_backend& result, const mpfr_float_backend& arg) BOOST_NOEXCEPT { mpfr_cosh(result.data(), arg.data(), GMP_RNDN); } -template -inline void eval_tanh(mpfr_float_backend& result, const mpfr_float_backend& arg) BOOST_NOEXCEPT +template +inline void eval_tanh(mpfr_float_backend& result, const mpfr_float_backend& arg) BOOST_NOEXCEPT { mpfr_tanh(result.data(), arg.data(), GMP_RNDN); } @@ -1073,8 +1344,8 @@ inline void eval_tanh(mpfr_float_backend& result, const mpfr_float_bac namespace detail{ -template -struct is_explicitly_convertible, backends::mpfr_float_backend > : public mpl::true_ {}; +template +struct is_explicitly_convertible, backends::mpfr_float_backend > : public mpl::true_ {}; } @@ -1091,6 +1362,9 @@ typedef number > mpfr_float_500; typedef number > mpfr_float_1000; typedef number > mpfr_float; +typedef number > static_mpfr_float_50; +typedef number > static_mpfr_float_100; + } // namespace multiprecision namespace math{ @@ -1117,14 +1391,14 @@ namespace std{ // // numeric_limits [partial] specializations for the types declared in this header: // -template -class numeric_limits, ExpressionTemplates> > +template +class numeric_limits, ExpressionTemplates> > { - typedef boost::multiprecision::number, ExpressionTemplates> number_type; + typedef boost::multiprecision::number, ExpressionTemplates> number_type; public: BOOST_STATIC_CONSTEXPR bool is_specialized = true; BOOST_STATIC_CONSTEXPR number_type (min)() BOOST_NOEXCEPT - { + { initializer.do_nothing(); static std::pair value; if(!value.first) @@ -1136,7 +1410,7 @@ public: return value.second; } BOOST_STATIC_CONSTEXPR number_type (max)() BOOST_NOEXCEPT - { + { initializer.do_nothing(); static std::pair value; if(!value.first) @@ -1159,8 +1433,8 @@ public: BOOST_STATIC_CONSTEXPR bool is_integer = false; BOOST_STATIC_CONSTEXPR bool is_exact = false; BOOST_STATIC_CONSTEXPR int radix = 2; - BOOST_STATIC_CONSTEXPR number_type epsilon() BOOST_NOEXCEPT - { + BOOST_STATIC_CONSTEXPR number_type epsilon() BOOST_NOEXCEPT + { initializer.do_nothing(); static std::pair value; if(!value.first) @@ -1172,8 +1446,8 @@ public: return value.second; } // What value should this be???? - BOOST_STATIC_CONSTEXPR number_type round_error() BOOST_NOEXCEPT - { + BOOST_STATIC_CONSTEXPR number_type round_error() BOOST_NOEXCEPT + { // returns epsilon/2 initializer.do_nothing(); static std::pair value; @@ -1194,8 +1468,8 @@ public: BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false; BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent; BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false; - BOOST_STATIC_CONSTEXPR number_type infinity() BOOST_NOEXCEPT - { + BOOST_STATIC_CONSTEXPR number_type infinity() BOOST_NOEXCEPT + { // returns epsilon/2 initializer.do_nothing(); static std::pair value; @@ -1207,8 +1481,8 @@ public: } return value.second; } - BOOST_STATIC_CONSTEXPR number_type quiet_NaN() BOOST_NOEXCEPT - { + BOOST_STATIC_CONSTEXPR number_type quiet_NaN() BOOST_NOEXCEPT + { // returns epsilon/2 initializer.do_nothing(); static std::pair value; @@ -1220,9 +1494,9 @@ public: } return value.second; } - BOOST_STATIC_CONSTEXPR number_type signaling_NaN() BOOST_NOEXCEPT - { - return number_type(0); + BOOST_STATIC_CONSTEXPR number_type signaling_NaN() BOOST_NOEXCEPT + { + return number_type(0); } BOOST_STATIC_CONSTEXPR number_type denorm_min() BOOST_NOEXCEPT { return number_type(0); } BOOST_STATIC_CONSTEXPR bool is_iec559 = false; @@ -1237,72 +1511,72 @@ private: { data_initializer() { - std::numeric_limits > >::epsilon(); - std::numeric_limits > >::round_error(); - (std::numeric_limits > >::min)(); - (std::numeric_limits > >::max)(); - std::numeric_limits > >::infinity(); - std::numeric_limits > >::quiet_NaN(); + std::numeric_limits > >::epsilon(); + std::numeric_limits > >::round_error(); + (std::numeric_limits > >::min)(); + (std::numeric_limits > >::max)(); + std::numeric_limits > >::infinity(); + std::numeric_limits > >::quiet_NaN(); } void do_nothing()const{} }; static const data_initializer initializer; }; -template -const typename numeric_limits, ExpressionTemplates> >::data_initializer numeric_limits, ExpressionTemplates> >::initializer; +template +const typename numeric_limits, ExpressionTemplates> >::data_initializer numeric_limits, ExpressionTemplates> >::initializer; #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION -template -BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::digits; -template -BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::digits10; -template -BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::max_digits10; -template -BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_signed; -template -BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_integer; -template -BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_exact; -template -BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::radix; -template -BOOST_CONSTEXPR_OR_CONST long numeric_limits, ExpressionTemplates> >::min_exponent; -template -BOOST_CONSTEXPR_OR_CONST long numeric_limits, ExpressionTemplates> >::min_exponent10; -template -BOOST_CONSTEXPR_OR_CONST long numeric_limits, ExpressionTemplates> >::max_exponent; -template -BOOST_CONSTEXPR_OR_CONST long numeric_limits, ExpressionTemplates> >::max_exponent10; -template -BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::has_infinity; -template -BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::has_quiet_NaN; -template -BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::has_signaling_NaN; -template -BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits, ExpressionTemplates> >::has_denorm; -template -BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::has_denorm_loss; -template -BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_iec559; -template -BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_bounded; -template -BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_modulo; -template -BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::traps; -template -BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::tinyness_before; -template -BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits, ExpressionTemplates> >::round_style; +template +BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::digits; +template +BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::digits10; +template +BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::max_digits10; +template +BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_signed; +template +BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_integer; +template +BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_exact; +template +BOOST_CONSTEXPR_OR_CONST int numeric_limits, ExpressionTemplates> >::radix; +template +BOOST_CONSTEXPR_OR_CONST long numeric_limits, ExpressionTemplates> >::min_exponent; +template +BOOST_CONSTEXPR_OR_CONST long numeric_limits, ExpressionTemplates> >::min_exponent10; +template +BOOST_CONSTEXPR_OR_CONST long numeric_limits, ExpressionTemplates> >::max_exponent; +template +BOOST_CONSTEXPR_OR_CONST long numeric_limits, ExpressionTemplates> >::max_exponent10; +template +BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::has_infinity; +template +BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::has_quiet_NaN; +template +BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::has_signaling_NaN; +template +BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits, ExpressionTemplates> >::has_denorm; +template +BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::has_denorm_loss; +template +BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_iec559; +template +BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_bounded; +template +BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::is_modulo; +template +BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::traps; +template +BOOST_CONSTEXPR_OR_CONST bool numeric_limits, ExpressionTemplates> >::tinyness_before; +template +BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits, ExpressionTemplates> >::round_style; #endif -template +template class numeric_limits, ExpressionTemplates> > { typedef boost::multiprecision::number, ExpressionTemplates> number_type; diff --git a/test/test_arithmetic.cpp b/test/test_arithmetic.cpp index 32f5a9d0..dd97caf4 100644 --- a/test/test_arithmetic.cpp +++ b/test/test_arithmetic.cpp @@ -1839,6 +1839,7 @@ int main() #endif #ifdef TEST_MPFR_50 test(); + test(); #endif #ifdef TEST_TOMMATH test();