From e28b1be017512d09b5cf2be205c2018300e58446 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Thu, 22 Oct 2015 10:11:16 +0100 Subject: [PATCH 1/7] Fix order-of-evalution bug in bitmask code. Allow mpfr_float to be used with Boost.Math by adding needed specializations. --- include/boost/multiprecision/mpfi.hpp | 2 +- include/boost/multiprecision/mpfr.hpp | 44 +++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/include/boost/multiprecision/mpfi.hpp b/include/boost/multiprecision/mpfi.hpp index 35e47b53..66a23cab 100644 --- a/include/boost/multiprecision/mpfi.hpp +++ b/include/boost/multiprecision/mpfi.hpp @@ -125,7 +125,7 @@ struct mpfi_float_imp { if(m_data[0].left._mpfr_d == 0) mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - boost::ulong_long_type mask = (((1uLL << (std::numeric_limits::digits - 1) - 1) << 1) | 1u); + boost::ulong_long_type mask = ((((1uLL << (std::numeric_limits::digits - 1)) - 1) << 1) | 1u); unsigned shift = 0; mpfi_t t; mpfi_init2(t, (std::max)(static_cast(std::numeric_limits::digits), static_cast(multiprecision::detail::digits10_2_2(digits10)))); diff --git a/include/boost/multiprecision/mpfr.hpp b/include/boost/multiprecision/mpfr.hpp index 80b34a39..fde558be 100644 --- a/include/boost/multiprecision/mpfr.hpp +++ b/include/boost/multiprecision/mpfr.hpp @@ -131,7 +131,7 @@ struct mpfr_float_imp { if(m_data[0]._mpfr_d == 0) mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - boost::ulong_long_type mask = (((1uLL << (std::numeric_limits::digits - 1) - 1) << 1) | 1uLL); + boost::ulong_long_type mask = ((((1uLL << (std::numeric_limits::digits - 1)) - 1) << 1) | 1uLL); unsigned shift = 0; mpfr_t t; mpfr_init2(t, (std::max)(static_cast(std::numeric_limits::digits), static_cast(multiprecision::detail::digits10_2_2(digits10)))); @@ -419,7 +419,7 @@ struct mpfr_float_imp #else mpfr_float_imp& operator = (boost::ulong_long_type i) { - boost::ulong_long_type mask = (((1uLL << (std::numeric_limits::digits - 1) - 1) << 1) | 1uL); + boost::ulong_long_type mask = ((((1uLL << (std::numeric_limits::digits - 1)) - 1) << 1) | 1uL); unsigned shift = 0; mpfr_t t; mp_limb_t t_limbs[limb_count]; @@ -1470,6 +1470,46 @@ inline int digits +inline boost::multiprecision::mpfr_float + max_value() +{ + boost::multiprecision::mpfr_float result(0.5); + mpfr_mul_2exp(result.backend().data(), result.backend().data(), mpfr_get_emax(), GMP_RNDN); + BOOST_ASSERT(mpfr_number_p(result.backend().data())); + return result; +} + +template <> +inline boost::multiprecision::mpfr_float + min_value() +{ + boost::multiprecision::mpfr_float result(0.5); + mpfr_div_2exp(result.backend().data(), result.backend().data(), -mpfr_get_emin(), GMP_RNDN); + BOOST_ASSERT(mpfr_number_p(result.backend().data())); + return result; +} + +template <> +inline boost::multiprecision::number, boost::multiprecision::et_off> + max_value, boost::multiprecision::et_off> >() +{ + boost::multiprecision::number, boost::multiprecision::et_off> result(0.5); + mpfr_mul_2exp(result.backend().data(), result.backend().data(), mpfr_get_emax(), GMP_RNDN); + BOOST_ASSERT(mpfr_number_p(result.backend().data())); + return result; +} + +template <> +inline boost::multiprecision::number, boost::multiprecision::et_off> + min_value, boost::multiprecision::et_off> >() +{ + boost::multiprecision::number, boost::multiprecision::et_off> result(0.5); + mpfr_div_2exp(result.backend().data(), result.backend().data(), -mpfr_get_emin(), GMP_RNDN); + BOOST_ASSERT(mpfr_number_p(result.backend().data())); + return result; +} + } // namespace tools namespace constants{ namespace detail{ From 7dfea115f8ddd78ef19a1d60bff04ecc93df7253 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Thu, 29 Oct 2015 09:58:28 +0000 Subject: [PATCH 2/7] Fix cpp_bin_float conversions, fix inverse trig logic to get as many digits as possible from std::asin. Add test case. Fixes: https://svn.boost.org/trac/boost/ticket/11764 --- .../boost/multiprecision/cpp_bin_float.hpp | 18 ++++++++- .../multiprecision/detail/functions/trig.hpp | 6 +-- test/Jamfile.v2 | 5 ++- test/test_float_conversions.cpp | 40 +++++++++++++++++++ 4 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 test/test_float_conversions.cpp diff --git a/include/boost/multiprecision/cpp_bin_float.hpp b/include/boost/multiprecision/cpp_bin_float.hpp index 6112a764..bdf6a630 100644 --- a/include/boost/multiprecision/cpp_bin_float.hpp +++ b/include/boost/multiprecision/cpp_bin_float.hpp @@ -43,7 +43,7 @@ public: typedef typename rep_type::signed_types signed_types; typedef typename rep_type::unsigned_types unsigned_types; - typedef boost::mpl::list float_types; + typedef boost::mpl::list float_types; typedef Exponent exponent_type; static const exponent_type max_exponent_limit = boost::integer_traits::const_max - 2 * static_cast(bit_count); @@ -104,6 +104,18 @@ public: this->assign_float(f); } + template + explicit cpp_bin_float(const Float& f, + typename boost::enable_if_c< + (number_category::value == number_kind_floating_point) + && (std::numeric_limits::digits > (int)bit_count) + && (std::numeric_limits::radix == 2) + >::type const* = 0) + : m_data(), m_exponent(0), m_sign(false) + { + this->assign_float(f); + } + cpp_bin_float& operator=(const cpp_bin_float &o) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval() = std::declval())) { m_data = o.m_data; @@ -125,7 +137,7 @@ public: template typename boost::enable_if_c< (number_category::value == number_kind_floating_point) - && (std::numeric_limits::digits <= (int)bit_count) + //&& (std::numeric_limits::digits <= (int)bit_count) && (std::numeric_limits::radix == 2), cpp_bin_float&>::type operator=(const Float& f) { return assign_float(f); @@ -1405,6 +1417,8 @@ namespace detail{ template struct is_explicitly_convertible, backends::cpp_bin_float > : public mpl::true_ {}; +template +struct is_explicitly_convertible > : public boost::is_floating_point {}; } #endif diff --git a/include/boost/multiprecision/detail/functions/trig.hpp b/include/boost/multiprecision/detail/functions/trig.hpp index 5d4e2639..76ce70fe 100644 --- a/include/boost/multiprecision/detail/functions/trig.hpp +++ b/include/boost/multiprecision/detail/functions/trig.hpp @@ -488,12 +488,12 @@ void eval_asin(T& result, const T& x) } // Get initial estimate using standard math function asin. - double dd; + long double dd; eval_convert_to(&dd, xx); - result = fp_type(std::asin(dd)); + result = (long double)(std::asin(dd)); - unsigned current_digits = std::numeric_limits::digits - 5; + unsigned current_digits = std::numeric_limits::digits - 5; unsigned target_precision = boost::multiprecision::detail::digits2 >::value; // Newton-Raphson iteration diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 24fcd81c..a499c9eb 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -681,7 +681,10 @@ run test_mixed_cpp_bin_float.cpp ; run test_mixed_cpp_dec_float.cpp ; run test_mixed_mpf_float.cpp gmp : : : [ check-target-builds ../config//has_gmp : : no ] ; run test_mixed_mpfr_float.cpp mpfr gmp : : : [ check-target-builds ../config//has_mpfr : : no ] ; - +# +# Check for narrowing conversions: +# +run test_float_conversions.cpp ; if $(enable-specfun) { diff --git a/test/test_float_conversions.cpp b/test/test_float_conversions.cpp new file mode 100644 index 00000000..4cb7f0a6 --- /dev/null +++ b/test/test_float_conversions.cpp @@ -0,0 +1,40 @@ +/////////////////////////////////////////////////////////////// +// Copyright 2015 John Maddock. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_ +// + +#ifdef _MSC_VER +# define _SCL_SECURE_NO_WARNINGS +#endif + +#include +#include +#include "test.hpp" + +#include +#include + +int main() +{ + using namespace boost::multiprecision; + + BOOST_STATIC_ASSERT(boost::is_convertible::value); + BOOST_STATIC_ASSERT(!boost::is_convertible::value); + BOOST_STATIC_ASSERT(!boost::is_convertible::value); + + cpp_bin_float_single s = boost::math::constants::pi(); + + typedef number, et_off> cpp_bin_float_half; + + BOOST_STATIC_ASSERT(!boost::is_convertible::value); + BOOST_STATIC_ASSERT(!boost::is_convertible::value); + BOOST_STATIC_ASSERT(!boost::is_convertible::value); + + cpp_bin_float_half hs = boost::math::constants::pi(); + + return boost::report_errors(); +} + + + From 1261cc6b8adbce0ab0902adf30676e146ab607f7 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Thu, 29 Oct 2015 11:29:26 +0000 Subject: [PATCH 3/7] Don't use long double asin if it's not available. --- .../boost/multiprecision/detail/functions/trig.hpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/include/boost/multiprecision/detail/functions/trig.hpp b/include/boost/multiprecision/detail/functions/trig.hpp index 76ce70fe..be2a9deb 100644 --- a/include/boost/multiprecision/detail/functions/trig.hpp +++ b/include/boost/multiprecision/detail/functions/trig.hpp @@ -486,14 +486,18 @@ void eval_asin(T& result, const T& x) result.negate(); return; } - +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + typedef typename boost::multiprecision::detail::canonical::type guess_type; +#else + typedef fp_type guess_type; +#endif // Get initial estimate using standard math function asin. - long double dd; + guess_type dd; eval_convert_to(&dd, xx); - result = (long double)(std::asin(dd)); + result = (guess_type)(std::asin(dd)); - unsigned current_digits = std::numeric_limits::digits - 5; + unsigned current_digits = std::numeric_limits::digits - 5; unsigned target_precision = boost::multiprecision::detail::digits2 >::value; // Newton-Raphson iteration From 360fcc9306b2ac7922d1805741f0ef29c34ef241 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Thu, 29 Oct 2015 12:39:53 +0000 Subject: [PATCH 4/7] Add missing return statement. See https://svn.boost.org/trac/boost/ticket/11762 --- include/boost/multiprecision/detail/default_ops.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/multiprecision/detail/default_ops.hpp b/include/boost/multiprecision/detail/default_ops.hpp index e3f38fc2..f76addb3 100644 --- a/include/boost/multiprecision/detail/default_ops.hpp +++ b/include/boost/multiprecision/detail/default_ops.hpp @@ -801,7 +801,7 @@ struct terminal { terminal(const R& v) : value(v){} terminal(){} - terminal& operator = (R val) { value = val; } + terminal& operator = (R val) { value = val; return *this; } R value; operator R()const { return value; } }; From 6f963e2f475d7b38c0401e90834a930bbb52a688 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Tue, 24 Nov 2015 19:11:00 +0000 Subject: [PATCH 5/7] Add more build options --- performance/Jamfile.v2 | 27 +++++++++++++++++++++++++++ performance/linpack-benchmark.cpp | 3 +++ 2 files changed, 30 insertions(+) diff --git a/performance/Jamfile.v2 b/performance/Jamfile.v2 index fbd67315..25bf24ad 100644 --- a/performance/Jamfile.v2 +++ b/performance/Jamfile.v2 @@ -100,6 +100,21 @@ obj obj_linpack_benchmark_double : linpack-benchmark.cpp : release ; +obj obj_linpack_benchmark_native_float128 : linpack-benchmark.cpp + : release + NATIVE_FLOAT128 + ; + +obj obj_linpack_benchmark_float128 : linpack-benchmark.cpp + : release + TEST_FLOAT128 + ; + +obj obj_linpack_benchmark_cpp_float_quad : linpack-benchmark.cpp + : release + TEST_CPP_BIN_FLOAT_QUAD + ; + lib f2c ; exe linpack_benchmark_mpfr : obj_linpack_benchmark_mpfr mpfr f2c gmp @@ -123,6 +138,18 @@ exe linpack_benchmark_double : obj_linpack_benchmark_double f2c : release ; +exe linpack_benchmark_native_float128 : obj_linpack_benchmark_native_float128 f2c + : release + ; + +exe linpack_benchmark_float128 : obj_linpack_benchmark_float128 f2c + : release + ; + +exe linpack_benchmark_cpp_quad_float : obj_linpack_benchmark_cpp_quad_float f2c + : release + ; + install miller_rabin_install : miller_rabin_performance : . ; install performance_test_install : performance_test : . ; install sf_performance_install : sf_performance : . ; diff --git a/performance/linpack-benchmark.cpp b/performance/linpack-benchmark.cpp index 104ac4c9..9178708b 100644 --- a/performance/linpack-benchmark.cpp +++ b/performance/linpack-benchmark.cpp @@ -58,6 +58,9 @@ double lexical_cast(const __float128& f) #elif defined(TEST_FLOAT128) #include typedef boost::multiprecision::float128 real_type; +#elif defined(TEST_CPP_BIN_FLOAT_QUAD) +#include +typedef boost::multiprecision::cpp_bin_float_quad real_type; #else typedef double real_type; #endif From 5af45646989df0924baa87b0c19c16f228b8ebfb Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Tue, 1 Dec 2015 15:58:26 +0000 Subject: [PATCH 6/7] Restrict noexcept on converting constructors. See https://svn.boost.org/trac/boost/ticket/11826. --- include/boost/multiprecision/float128.hpp | 4 ++-- test/test_nothrow_float128.cpp | 25 +++++++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/include/boost/multiprecision/float128.hpp b/include/boost/multiprecision/float128.hpp index cd70fa00..43416723 100644 --- a/include/boost/multiprecision/float128.hpp +++ b/include/boost/multiprecision/float128.hpp @@ -144,10 +144,10 @@ public: return *this; } template - BOOST_CONSTEXPR float128_backend(const T& i, const typename enable_if_c::value>::type* = 0) BOOST_NOEXCEPT + BOOST_CONSTEXPR float128_backend(const T& i, const typename enable_if_c::value>::type* = 0) BOOST_NOEXCEPT_IF(noexcept(std::declval() = std::declval())) : m_value(i) {} template - typename enable_if_c::value || is_convertible::value, float128_backend&>::type operator = (const T& i) BOOST_NOEXCEPT + typename enable_if_c::value || is_convertible::value, float128_backend&>::type operator = (const T& i) BOOST_NOEXCEPT_IF(noexcept(std::declval() = std::declval())) { m_value = i; return *this; diff --git a/test/test_nothrow_float128.cpp b/test/test_nothrow_float128.cpp index c41678e3..6b377f55 100644 --- a/test/test_nothrow_float128.cpp +++ b/test/test_nothrow_float128.cpp @@ -48,6 +48,31 @@ BOOST_STATIC_ASSERT(boost::has_nothrow_copy::va BOOST_STATIC_ASSERT(boost::has_nothrow_assign::value); #endif +BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::float128())); +BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::float128(std::declval()))); +BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::float128(std::declval()))); +BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::float128(std::declval()))); +BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::float128(std::declval()))); +BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::float128(std::declval()))); +BOOST_STATIC_ASSERT(noexcept(boost::multiprecision::float128(std::declval()))); +BOOST_STATIC_ASSERT(noexcept(std::declval() = std::declval())); +BOOST_STATIC_ASSERT(noexcept(std::declval() = std::declval())); +BOOST_STATIC_ASSERT(noexcept(std::declval() = std::declval())); +BOOST_STATIC_ASSERT(noexcept(std::declval() = std::declval())); +BOOST_STATIC_ASSERT(noexcept(std::declval() = std::declval())); +BOOST_STATIC_ASSERT(noexcept(std::declval() = std::declval())); + +struct any_convert +{ + template + operator T ()const; // Can throw! +}; + +BOOST_STATIC_ASSERT(!noexcept(boost::multiprecision::float128(std::declval()))); +BOOST_STATIC_ASSERT(!noexcept(boost::multiprecision::float128(std::declval()))); +BOOST_STATIC_ASSERT(!noexcept(std::declval() = std::declval())); +BOOST_STATIC_ASSERT(!noexcept(std::declval() = std::declval())); + #endif // noexcept From ff3f04ef2e61f69f80bcae801cccc1213a59651b Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Tue, 8 Dec 2015 19:09:54 +0000 Subject: [PATCH 7/7] Document changes for this release. --- .../boost_multiprecision/indexes/s01.html | 96 +++++++++++++-- .../boost_multiprecision/indexes/s02.html | 2 +- .../boost_multiprecision/indexes/s03.html | 2 +- .../boost_multiprecision/indexes/s04.html | 113 +++++++++++++++++- doc/html/boost_multiprecision/map/hist.html | 49 ++++++-- doc/html/index.html | 2 +- doc/multiprecision.qbk | 11 ++ 7 files changed, 249 insertions(+), 26 deletions(-) diff --git a/doc/html/boost_multiprecision/indexes/s01.html b/doc/html/boost_multiprecision/indexes/s01.html index f62255b8..1dd06ae5 100644 --- a/doc/html/boost_multiprecision/indexes/s01.html +++ b/doc/html/boost_multiprecision/indexes/s01.html @@ -24,14 +24,21 @@

-Function Index

-

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

+Function Index
+

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

A
D @@ -128,6 +139,15 @@
  • +

    denominator

    + +
  • +
  • divide_qr

    F @@ -413,6 +441,13 @@
    -O +N
    +
    +O +
    +
    +
  • +
    P

    C D E F G I L M N T

    diff --git a/doc/html/boost_multiprecision/indexes/s03.html b/doc/html/boost_multiprecision/indexes/s03.html index 6c28ee40..7bc4bcd0 100644 --- a/doc/html/boost_multiprecision/indexes/s03.html +++ b/doc/html/boost_multiprecision/indexes/s03.html @@ -24,7 +24,7 @@

    -Typedef Index

    +Typedef Index

    C F I L M S T U

    diff --git a/doc/html/boost_multiprecision/indexes/s04.html b/doc/html/boost_multiprecision/indexes/s04.html index b64ee567..00a9a901 100644 --- a/doc/html/boost_multiprecision/indexes/s04.html +++ b/doc/html/boost_multiprecision/indexes/s04.html @@ -23,7 +23,7 @@

    -Index

    +Index

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

    @@ -31,6 +31,13 @@
  • +

    Constructing and Interconverting Between Number Types

    + +
  • +
  • convert_to

  • @@ -238,6 +249,7 @@
  • cpp_dec_float

  • cpp_dec_float_100

  • cpp_dec_float_50

  • +
  • TODO

  • @@ -291,6 +303,8 @@
  • cpp_int

  • cpp_rational

  • cpp_rational_backend

  • +
  • denominator

  • +
  • numerator

  • @@ -322,6 +336,19 @@
  • +

    Defining a Special Function.

    + +
  • +
  • +

    denominator

    + +
  • +
  • divide_qr

  • @@ -675,8 +711,10 @@

    gmp_rational

  • @@ -686,6 +724,13 @@
  • @@ -876,7 +928,9 @@
  • Mixed Precision Arithmetic

    @@ -1025,7 +1079,9 @@
  • component_type

  • convert_to

  • default_precision

  • +
  • denominator

  • divide_qr

  • +
  • exp

  • expression_template_default

  • fpclassify

  • frexp

  • @@ -1049,6 +1105,8 @@
  • multiply

  • number

  • number_category

  • +
  • numerator

  • +
  • pow

  • powm

  • precision

  • round

  • @@ -1057,6 +1115,7 @@
  • str

  • subtract

  • swap

  • +
  • the

  • trunc

  • value

  • @@ -1065,12 +1124,25 @@

    number_category

    +
  • +

    numerator

    + +
  • O
    - + Multiprecision-2.2.3 (Boost-1.57)
    @@ -91,7 +120,7 @@
    - + Multiprecision-2.2.2 (Boost-1.56)
    @@ -104,14 +133,14 @@
    - + Multiprecision-2.2.1
    • Fix bug in assignment from string in cpp_int, see 9936.
    - + Multiprecision-2.2.0
      @@ -139,7 +168,7 @@
    - + Boost-1.55
      @@ -177,7 +206,7 @@
    - + 1.54
      @@ -232,7 +261,7 @@
    - + 1.53
      @@ -248,7 +277,7 @@
    - + Post review changes
    @@ -302,7 +331,7 @@
    - + Pre-review history
    diff --git a/doc/html/index.html b/doc/html/index.html index f632b7b2..a1647bd8 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -165,7 +165,7 @@ - +

    Last revised: October 18, 2015 at 11:03:06 GMT

    Last revised: December 08, 2015 at 19:08:52 GMT


    diff --git a/doc/multiprecision.qbk b/doc/multiprecision.qbk index 86c4bd3d..28a6e186 100644 --- a/doc/multiprecision.qbk +++ b/doc/multiprecision.qbk @@ -5074,6 +5074,17 @@ Windows Vista machine. [section:hist History] +[h4 Multiprecision-2.2.6 (Boost-1.60)] + +* Fixed result of Miller Rabin primality test for value 2, see [@https://svn.boost.org/trac/boost/ticket/11495 #11495]. +* Improved initialization of cpp_int from very large strings of hex or octal digits, see [@https://svn.boost.org/trac/boost/ticket/11590 #11590]. +* Fixed fmod behaviour for negative divisors, see [@https://svn.boost.org/trac/boost/ticket/11641 #11641]. +* Fixed infinite division loop in cpp_int special case, see [@https://svn.boost.org/trac/boost/ticket/11648 #11648]. +* Patched missing return statement in [@https://svn.boost.org/trac/boost/ticket/11762 #11762]. +* Fixed mixed mode arithmetic compiler error in [@https://svn.boost.org/trac/boost/ticket/11764 #11764]. +* Fixed over-aggressive use of noexcept in [@https://svn.boost.org/trac/boost/ticket/11826 #11826]. + + [h4 Multiprecision-2.2.5 (Boost-1.59)] * Depricated boost/multiprecision/random.hpp as it's no longer needed, updated random examples to match.