From 468b4791f61654cae657fa48440239c50de1ab16 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Thu, 26 Mar 2015 16:26:48 +0000 Subject: [PATCH 01/33] Fix build on systems with no . --- example/Jamfile.v2 | 2 +- example/hypergeometric_luke_algorithms.cpp | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/example/Jamfile.v2 b/example/Jamfile.v2 index 5ed5752a..57e1be1b 100644 --- a/example/Jamfile.v2 +++ b/example/Jamfile.v2 @@ -78,7 +78,7 @@ run debug_adaptor_snips.cpp ; run float128_snips.cpp quadmath : : : [ check-target-builds ../config//has_float128 : : no ] ; run floating_point_examples.cpp ; run gauss_laguerre_quadrature.cpp : : : release [ requires cxx11_lambdas ] ; -run hypergeometric_luke_algorithms.cpp : : : [ requires cxx11_nullptr ] ; +run hypergeometric_luke_algorithms.cpp ../../chrono/build//boost_chrono ../../system/build//boost_system : : : [ requires cxx11_nullptr ] ; run integer_examples.cpp ; run logged_adaptor.cpp mpfi mpfr gmp : : : [ check-target-builds ../config//has_mpfi : : no ] ; run mixed_integer_arithmetic.cpp ; diff --git a/example/hypergeometric_luke_algorithms.cpp b/example/hypergeometric_luke_algorithms.cpp index f7ff1c4b..07fc90e9 100644 --- a/example/hypergeometric_luke_algorithms.cpp +++ b/example/hypergeometric_luke_algorithms.cpp @@ -30,9 +30,7 @@ #define DIGIT_COUNT 100 #endif -#define HAS_STD_CHRONO - -#if defined(HAS_STD_CHRONO) +#if !defined(BOOST_NO_CXX11_HDR_CHRONO) #include #define STD_CHRONO std::chrono #else From 942b79dad03352ab843624e1f2e6cb2bd8ff686a Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Sun, 29 Mar 2015 11:34:20 +0100 Subject: [PATCH 02/33] Fix conversions from long long to take long sized chunks. Also fixed some bitmasks, and added feature-detection checks. --- include/boost/multiprecision/gmp.hpp | 87 ++++++++++++++++++--------- include/boost/multiprecision/mpfi.hpp | 17 ++++-- include/boost/multiprecision/mpfr.hpp | 32 +++++++--- 3 files changed, 94 insertions(+), 42 deletions(-) diff --git a/include/boost/multiprecision/gmp.hpp b/include/boost/multiprecision/gmp.hpp index 3b020d07..0ab8346a 100644 --- a/include/boost/multiprecision/gmp.hpp +++ b/include/boost/multiprecision/gmp.hpp @@ -59,10 +59,15 @@ namespace detail{ template struct gmp_float_imp { - typedef mpl::list signed_types; +#ifdef BOOST_HAS_LONG_LONG + typedef mpl::list signed_types; typedef mpl::list unsigned_types; - typedef mpl::list float_types; - typedef long exponent_type; +#else + typedef mpl::list signed_types; + typedef mpl::list unsigned_types; +#endif + typedef mpl::list float_types; + typedef long exponent_type; gmp_float_imp() BOOST_NOEXCEPT {} @@ -100,27 +105,36 @@ struct gmp_float_imp return *this; } #endif + +#ifdef BOOST_HAS_LONG_LONG +#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX) + gmp_float_imp& operator = (unsigned long long i) + { + *this = static_cast(i); + } +#else gmp_float_imp& operator = (unsigned long long i) { if(m_data[0]._mp_d == 0) mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - unsigned long long mask = ((1uLL << std::numeric_limits::digits) - 1); + unsigned long long mask = ((((1uLL << (std::numeric_limits::digits - 1)) - 1) << 1) | 1uLL); unsigned shift = 0; mpf_t t; mpf_init2(t, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); mpf_set_ui(m_data, 0); while(i) { - mpf_set_ui(t, static_cast(i & mask)); + mpf_set_ui(t, static_cast(i & mask)); if(shift) mpf_mul_2exp(t, t, shift); mpf_add(m_data, m_data, t); - shift += std::numeric_limits::digits; - i >>= std::numeric_limits::digits; + shift += std::numeric_limits::digits; + i >>= std::numeric_limits::digits; } mpf_clear(t); return *this; } +#endif gmp_float_imp& operator = (long long i) { if(m_data[0]._mp_d == 0) @@ -131,6 +145,7 @@ struct gmp_float_imp mpf_neg(m_data, m_data); return *this; } +#endif gmp_float_imp& operator = (unsigned long i) { if(m_data[0]._mp_d == 0) @@ -969,8 +984,13 @@ inline void eval_frexp(gmp_float& result, const gmp_float& v struct gmp_int { +#ifdef BOOST_HAS_LONG_LONG typedef mpl::list signed_types; typedef mpl::list unsigned_types; +#else + typedef mpl::list signed_types; + typedef mpl::list unsigned_types; +#endif typedef mpl::list float_types; gmp_int() @@ -1026,27 +1046,35 @@ struct gmp_int return *this; } #endif +#ifdef BOOST_HAS_LONG_LONG +#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX) + gmp_int& operator = (unsigned long long i) + { + *this = static_cast(i); + } +#else gmp_int& operator = (unsigned long long i) { if(m_data[0]._mp_d == 0) mpz_init(this->m_data); - unsigned long long mask = ((1uLL << std::numeric_limits::digits) - 1); + unsigned long long mask = ((((1uLL << (std::numeric_limits::digits - 1)) - 1) << 1) | 1uLL); unsigned shift = 0; mpz_t t; mpz_set_ui(m_data, 0); mpz_init_set_ui(t, 0); while(i) { - mpz_set_ui(t, static_cast(i & mask)); + mpz_set_ui(t, static_cast(i & mask)); if(shift) mpz_mul_2exp(t, t, shift); mpz_add(m_data, m_data, t); - shift += std::numeric_limits::digits; - i >>= std::numeric_limits::digits; + shift += std::numeric_limits::digits; + i >>= std::numeric_limits::digits; } mpz_clear(t); return *this; } +#endif gmp_int& operator = (long long i) { if(m_data[0]._mp_d == 0) @@ -1057,6 +1085,7 @@ struct gmp_int mpz_neg(m_data, m_data); return *this; } +#endif gmp_int& operator = (unsigned long i) { if(m_data[0]._mp_d == 0) @@ -1706,9 +1735,14 @@ void eval_add(gmp_rational& t, const gmp_rational& o); struct gmp_rational { - typedef mpl::list signed_types; +#ifdef BOOST_HAS_LONG_LONG + typedef mpl::list signed_types; typedef mpl::list unsigned_types; - typedef mpl::list float_types; +#else + typedef mpl::list signed_types; + typedef mpl::list unsigned_types; +#endif + typedef mpl::list float_types; gmp_rational() { @@ -1757,25 +1791,20 @@ struct gmp_rational return *this; } #endif +#ifdef BOOST_HAS_LONG_LONG +#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX) + gmp_rational& operator = (unsigned long long i) + { + *this = static_cast(i); + } +#else gmp_rational& operator = (unsigned long long i) { if(m_data[0]._mp_den._mp_d == 0) mpq_init(m_data); - unsigned long long mask = ((1uLL << std::numeric_limits::digits) - 1); - unsigned shift = 0; - mpq_t t; - mpq_set_ui(m_data, 0, 1); - mpq_init(t); - while(i) - { - mpq_set_ui(t, static_cast(i & mask), 1); - if(shift) - mpq_mul_2exp(t, t, shift); - mpq_add(m_data, m_data, t); - shift += std::numeric_limits::digits; - i >>= std::numeric_limits::digits; - } - mpq_clear(t); + gmp_int zi; + zi = i; + mpq_set_z(m_data, zi.data()); return *this; } gmp_rational& operator = (long long i) @@ -1788,6 +1817,8 @@ struct gmp_rational mpq_neg(m_data, m_data); return *this; } +#endif +#endif gmp_rational& operator = (unsigned long i) { if(m_data[0]._mp_den._mp_d == 0) diff --git a/include/boost/multiprecision/mpfi.hpp b/include/boost/multiprecision/mpfi.hpp index 81503f71..68b77797 100644 --- a/include/boost/multiprecision/mpfi.hpp +++ b/include/boost/multiprecision/mpfi.hpp @@ -55,8 +55,13 @@ struct mpfi_float_imp; template struct mpfi_float_imp { +#ifdef BOOST_HAS_LONG_LONG typedef mpl::list signed_types; typedef mpl::list unsigned_types; +#else + typedef mpl::list signed_types; + typedef mpl::list unsigned_types; +#endif typedef mpl::list float_types; typedef long exponent_type; @@ -97,6 +102,7 @@ struct mpfi_float_imp return *this; } #endif +#ifdef BOOST_HAS_LONG_LONG #ifdef _MPFR_H_HAVE_INTMAX_T mpfi_float_imp& operator = (unsigned long long i) { @@ -119,19 +125,19 @@ 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())); - unsigned long long mask = ((1uLL << std::numeric_limits::digits) - 1); + unsigned long long 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)))); + mpfi_init2(t, (std::max)(static_cast(std::numeric_limits::digits), static_cast(multiprecision::detail::digits10_2_2(digits10)))); mpfi_set_ui(m_data, 0); while(i) { - mpfi_set_ui(t, static_cast(i & mask)); + mpfi_set_ui(t, static_cast(i & mask)); if(shift) mpfi_mul_2exp(t, t, shift); mpfi_add(m_data, m_data, t); - shift += std::numeric_limits::digits; - i >>= std::numeric_limits::digits; + shift += std::numeric_limits::digits; + i >>= std::numeric_limits::digits; } mpfi_clear(t); return *this; @@ -146,6 +152,7 @@ struct mpfi_float_imp mpfi_neg(m_data, m_data); return *this; } +#endif #endif mpfi_float_imp& operator = (unsigned long i) { diff --git a/include/boost/multiprecision/mpfr.hpp b/include/boost/multiprecision/mpfr.hpp index 36298c14..d9327e28 100644 --- a/include/boost/multiprecision/mpfr.hpp +++ b/include/boost/multiprecision/mpfr.hpp @@ -63,8 +63,13 @@ struct mpfr_float_imp; template struct mpfr_float_imp { +#ifdef BOOST_HAS_LONG_LONG typedef mpl::list signed_types; typedef mpl::list unsigned_types; +#else + typedef mpl::list signed_types; + typedef mpl::list unsigned_types; +#endif typedef mpl::list float_types; typedef long exponent_type; @@ -105,6 +110,7 @@ struct mpfr_float_imp return *this; } #endif +#ifdef BOOST_HAS_LONG_LONG #ifdef _MPFR_H_HAVE_INTMAX_T mpfr_float_imp& operator = (unsigned long long i) { @@ -125,19 +131,19 @@ 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())); - unsigned long long mask = ((1uLL << std::numeric_limits::digits) - 1); + unsigned long long 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)))); + mpfr_init2(t, (std::max)(static_cast(std::numeric_limits::digits), static_cast(multiprecision::detail::digits10_2_2(digits10)))); mpfr_set_ui(m_data, 0, GMP_RNDN); while(i) { - mpfr_set_ui(t, static_cast(i & mask), GMP_RNDN); + 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; + shift += std::numeric_limits::digits; + i >>= std::numeric_limits::digits; } mpfr_clear(t); return *this; @@ -152,6 +158,7 @@ struct mpfr_float_imp mpfr_neg(m_data, m_data, GMP_RNDN); return *this; } +#endif #endif mpfr_float_imp& operator = (unsigned long i) { @@ -363,8 +370,13 @@ protected: template struct mpfr_float_imp { +#ifdef BOOST_HAS_LONG_LONG typedef mpl::list signed_types; typedef mpl::list unsigned_types; +#else + typedef mpl::list signed_types; + typedef mpl::list unsigned_types; +#endif typedef mpl::list float_types; typedef long exponent_type; @@ -392,6 +404,7 @@ struct mpfr_float_imp mpfr_set(m_data, o.m_data, GMP_RNDN); return *this; } +#ifdef BOOST_HAS_LONG_LONG #ifdef _MPFR_H_HAVE_INTMAX_T mpfr_float_imp& operator = (unsigned long long i) { @@ -406,7 +419,7 @@ struct mpfr_float_imp #else mpfr_float_imp& operator = (unsigned long long i) { - unsigned long long mask = ((1uLL << std::numeric_limits::digits) - 1); + unsigned long long mask = (((1uLL << (std::numeric_limits::digits - 1) - 1) << 1) | 1uL); unsigned shift = 0; mpfr_t t; mp_limb_t t_limbs[limb_count]; @@ -415,12 +428,12 @@ struct mpfr_float_imp mpfr_set_ui(m_data, 0, GMP_RNDN); while(i) { - mpfr_set_ui(t, static_cast(i & mask), GMP_RNDN); + 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; + shift += std::numeric_limits::digits; + i >>= std::numeric_limits::digits; } return *this; } @@ -432,6 +445,7 @@ struct mpfr_float_imp mpfr_neg(m_data, m_data, GMP_RNDN); return *this; } +#endif #endif mpfr_float_imp& operator = (unsigned long i) { From 4c816e1b2f2711adb460b60c07536973e7aacd56 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Sun, 29 Mar 2015 17:53:07 +0100 Subject: [PATCH 03/33] Replace long long with boost::long_long_type to avoid GCC warnings/errors in pedantic mode. Fix missing return statements on new long long code. --- .../concepts/mp_number_archetypes.hpp | 20 +- .../boost/multiprecision/cpp_bin_float.hpp | 20 +- .../boost/multiprecision/cpp_dec_float.hpp | 198 +++++++++--------- include/boost/multiprecision/cpp_int.hpp | 8 +- .../boost/multiprecision/cpp_int/checked.hpp | 4 +- .../multiprecision/cpp_int/cpp_int_config.hpp | 10 +- .../boost/multiprecision/detail/bitscan.hpp | 10 +- .../multiprecision/detail/default_ops.hpp | 44 ++-- .../detail/generic_interconvert.hpp | 6 +- .../multiprecision/detail/number_base.hpp | 6 +- include/boost/multiprecision/float128.hpp | 4 +- include/boost/multiprecision/gmp.hpp | 53 ++--- include/boost/multiprecision/integer.hpp | 6 +- include/boost/multiprecision/mpfi.hpp | 20 +- include/boost/multiprecision/mpfr.hpp | 34 +-- include/boost/multiprecision/tommath.hpp | 14 +- 16 files changed, 230 insertions(+), 227 deletions(-) diff --git a/include/boost/multiprecision/concepts/mp_number_archetypes.hpp b/include/boost/multiprecision/concepts/mp_number_archetypes.hpp index e52044ad..5d5d8417 100644 --- a/include/boost/multiprecision/concepts/mp_number_archetypes.hpp +++ b/include/boost/multiprecision/concepts/mp_number_archetypes.hpp @@ -26,8 +26,8 @@ namespace concepts{ struct number_backend_float_architype { - typedef mpl::list signed_types; - typedef mpl::list unsigned_types; + typedef mpl::list signed_types; + typedef mpl::list unsigned_types; typedef mpl::list float_types; typedef int exponent_type; @@ -46,13 +46,13 @@ struct number_backend_float_architype std::cout << "Assignment (" << m_value << ")" << std::endl; return *this; } - number_backend_float_architype& operator = (unsigned long long i) + number_backend_float_architype& operator = (boost::ulong_long_type i) { m_value = i; std::cout << "UInt Assignment (" << i << ")" << std::endl; return *this; } - number_backend_float_architype& operator = (long long i) + number_backend_float_architype& operator = (boost::long_long_type i) { m_value = i; std::cout << "Int Assignment (" << i << ")" << std::endl; @@ -112,12 +112,12 @@ struct number_backend_float_architype std::cout << "Comparison" << std::endl; return m_value > o.m_value ? 1 : (m_value < o.m_value ? -1 : 0); } - int compare(long long i)const + int compare(boost::long_long_type i)const { std::cout << "Comparison with int" << std::endl; return m_value > i ? 1 : (m_value < i ? -1 : 0); } - int compare(unsigned long long i)const + int compare(boost::ulong_long_type i)const { std::cout << "Comparison with unsigned" << std::endl; return m_value > i ? 1 : (m_value < i ? -1 : 0); @@ -151,13 +151,13 @@ inline void eval_divide(number_backend_float_architype& result, const number_bac result.m_value /= o.m_value; } -inline void eval_convert_to(unsigned long long* result, const number_backend_float_architype& val) +inline void eval_convert_to(boost::ulong_long_type* result, const number_backend_float_architype& val) { - *result = static_cast(val.m_value); + *result = static_cast(val.m_value); } -inline void eval_convert_to(long long* result, const number_backend_float_architype& val) +inline void eval_convert_to(boost::long_long_type* result, const number_backend_float_architype& val) { - *result = static_cast(val.m_value); + *result = static_cast(val.m_value); } inline void eval_convert_to(long double* result, number_backend_float_architype& val) { diff --git a/include/boost/multiprecision/cpp_bin_float.hpp b/include/boost/multiprecision/cpp_bin_float.hpp index 9a4ceff5..1b11c782 100644 --- a/include/boost/multiprecision/cpp_bin_float.hpp +++ b/include/boost/multiprecision/cpp_bin_float.hpp @@ -1045,7 +1045,7 @@ inline bool eval_eq(const cpp_bin_float -inline void eval_convert_to(long long *res, const cpp_bin_float &arg) +inline void eval_convert_to(boost::long_long_type *res, const cpp_bin_float &arg) { switch(arg.exponent()) { @@ -1055,7 +1055,7 @@ inline void eval_convert_to(long long *res, const cpp_bin_float::exponent_nan: BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer.")); case cpp_bin_float::exponent_infinity: - *res = (std::numeric_limits::max)(); + *res = (std::numeric_limits::max)(); if(arg.sign()) *res = -*res; return; @@ -1068,14 +1068,14 @@ inline void eval_convert_to(long long *res, const cpp_bin_float::min)()) <= 0)) + if(arg.sign() && (arg.compare((std::numeric_limits::min)()) <= 0)) { - *res = (std::numeric_limits::min)(); + *res = (std::numeric_limits::min)(); return; } - else if(!arg.sign() && (arg.compare((std::numeric_limits::max)()) >= 0)) + else if(!arg.sign() && (arg.compare((std::numeric_limits::max)()) >= 0)) { - *res = (std::numeric_limits::max)(); + *res = (std::numeric_limits::max)(); return; } eval_right_shift(man, shift); @@ -1087,7 +1087,7 @@ inline void eval_convert_to(long long *res, const cpp_bin_float -inline void eval_convert_to(unsigned long long *res, const cpp_bin_float &arg) +inline void eval_convert_to(boost::ulong_long_type *res, const cpp_bin_float &arg) { switch(arg.exponent()) { @@ -1097,7 +1097,7 @@ inline void eval_convert_to(unsigned long long *res, const cpp_bin_float::exponent_nan: BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer.")); case cpp_bin_float::exponent_infinity: - *res = (std::numeric_limits::max)(); + *res = (std::numeric_limits::max)(); return; } typename cpp_bin_float::rep_type man(arg.bits()); @@ -1110,8 +1110,8 @@ inline void eval_convert_to(unsigned long long *res, const cpp_bin_float::bit_count than a long long? - *res = (std::numeric_limits::max)(); + // TODO: what if we have fewer cpp_bin_float::bit_count than a boost::long_long_type? + *res = (std::numeric_limits::max)(); return; } eval_right_shift(man, shift); diff --git a/include/boost/multiprecision/cpp_dec_float.hpp b/include/boost/multiprecision/cpp_dec_float.hpp index d19abafe..ba0800bb 100644 --- a/include/boost/multiprecision/cpp_dec_float.hpp +++ b/include/boost/multiprecision/cpp_dec_float.hpp @@ -59,8 +59,8 @@ private: BOOST_STATIC_ASSERT_MSG(sizeof(ExponentType) > 1, "ExponentType is too small."); public: - typedef mpl::list signed_types; - typedef mpl::list unsigned_types; + typedef mpl::list signed_types; + typedef mpl::list unsigned_types; typedef mpl::list float_types; typedef ExponentType exponent_type; @@ -284,21 +284,21 @@ public: static const cpp_dec_float& zero() { init.do_nothing(); - static cpp_dec_float val(static_cast(0u)); + static cpp_dec_float val(static_cast(0u)); return val; } static const cpp_dec_float& one() { init.do_nothing(); - static cpp_dec_float val(static_cast(1u)); + static cpp_dec_float val(static_cast(1u)); return val; } static const cpp_dec_float& two() { init.do_nothing(); - static cpp_dec_float val(static_cast(2u)); + static cpp_dec_float val(static_cast(2u)); return val; } @@ -348,21 +348,21 @@ public: static const cpp_dec_float& long_long_max() { init.do_nothing(); - static cpp_dec_float val((std::numeric_limits::max)()); + static cpp_dec_float val((std::numeric_limits::max)()); return val; } static const cpp_dec_float& long_long_min() { init.do_nothing(); - static cpp_dec_float val((std::numeric_limits::min)()); + static cpp_dec_float val((std::numeric_limits::min)()); return val; } static const cpp_dec_float& ulong_long_max() { init.do_nothing(); - static cpp_dec_float val((std::numeric_limits::max)()); + static cpp_dec_float val((std::numeric_limits::max)()); return val; } @@ -397,7 +397,7 @@ public: return *this; } - cpp_dec_float& operator=(long long v) + cpp_dec_float& operator=(boost::long_long_type v) { if(v < 0) { @@ -409,7 +409,7 @@ public: return *this; } - cpp_dec_float& operator=(unsigned long long v) + cpp_dec_float& operator=(boost::ulong_long_type v) { from_unsigned_long_long(v); return *this; @@ -428,22 +428,22 @@ public: cpp_dec_float& operator*=(const cpp_dec_float& v); cpp_dec_float& operator/=(const cpp_dec_float& v); - cpp_dec_float& add_unsigned_long_long(const unsigned long long n) + cpp_dec_float& add_unsigned_long_long(const boost::ulong_long_type n) { cpp_dec_float t; t.from_unsigned_long_long(n); return *this += t; } - cpp_dec_float& sub_unsigned_long_long(const unsigned long long n) + cpp_dec_float& sub_unsigned_long_long(const boost::ulong_long_type n) { cpp_dec_float t; t.from_unsigned_long_long(n); return *this -= t; } - cpp_dec_float& mul_unsigned_long_long(const unsigned long long n); - cpp_dec_float& div_unsigned_long_long(const unsigned long long n); + cpp_dec_float& mul_unsigned_long_long(const boost::ulong_long_type n); + cpp_dec_float& div_unsigned_long_long(const boost::ulong_long_type n); // Elementary primitives. cpp_dec_float& calculate_inv (); @@ -503,8 +503,8 @@ public: double extract_double() const; long double extract_long_double() const; - signed long long extract_signed_long_long() const; - unsigned long long extract_unsigned_long_long() const; + boost::long_long_type extract_signed_long_long() const; + boost::ulong_long_type extract_unsigned_long_long() const; void extract_parts(double& mantissa, ExponentType& exponent) const; cpp_dec_float extract_integer_part() const; @@ -522,7 +522,7 @@ public: prec_elem = (std::min)(cpp_dec_float_elem_number, (std::max)(elems, static_cast(2))); } } - static cpp_dec_float pow2(long long i); + static cpp_dec_float pow2(boost::long_long_type i); ExponentType order()const { const bool bo_order_is_zero = ((!(isfinite)()) || (data[0] == static_cast(0u))); @@ -590,7 +590,7 @@ private: static bool data_elem_is_non_nine_predicate(const boost::uint32_t& d) { return (d != static_cast(cpp_dec_float::cpp_dec_float_elem_mask - 1)); } static bool char_is_nonzero_predicate(const char& c) { return (c != static_cast('0')); } - void from_unsigned_long_long(const unsigned long long u); + void from_unsigned_long_long(const boost::ulong_long_type u); int cmp_data(const array_type& vd) const; @@ -970,9 +970,9 @@ cpp_dec_float& cpp_dec_float -cpp_dec_float& cpp_dec_float::mul_unsigned_long_long(const unsigned long long n) +cpp_dec_float& cpp_dec_float::mul_unsigned_long_long(const boost::ulong_long_type n) { - // Multiply *this with a constant unsigned long long. + // Multiply *this with a constant boost::ulong_long_type. // Evaluate the sign of the result. const bool b_neg = neg; @@ -1003,7 +1003,7 @@ cpp_dec_float& cpp_dec_float= static_cast(cpp_dec_float_elem_mask)) + if(n >= static_cast(cpp_dec_float_elem_mask)) { neg = b_neg; cpp_dec_float t; @@ -1011,7 +1011,7 @@ cpp_dec_float& cpp_dec_float(1u)) + if(n == static_cast(1u)) { neg = b_neg; return *this; @@ -1050,9 +1050,9 @@ cpp_dec_float& cpp_dec_float -cpp_dec_float& cpp_dec_float::div_unsigned_long_long(const unsigned long long n) +cpp_dec_float& cpp_dec_float::div_unsigned_long_long(const boost::ulong_long_type n) { - // Divide *this by a constant unsigned long long. + // Divide *this by a constant boost::ulong_long_type. // Evaluate the sign of the result. const bool b_neg = neg; @@ -1074,7 +1074,7 @@ cpp_dec_float& cpp_dec_float(0u)) + if(n == static_cast(0u)) { // Divide by 0. if(iszero()) @@ -1096,7 +1096,7 @@ cpp_dec_float& cpp_dec_float= static_cast(cpp_dec_float_elem_mask)) + if(n >= static_cast(cpp_dec_float_elem_mask)) { neg = b_neg; cpp_dec_float t; @@ -1584,58 +1584,58 @@ long double cpp_dec_float::extract_long_doubl } template -signed long long cpp_dec_float::extract_signed_long_long() const +boost::long_long_type cpp_dec_float::extract_signed_long_long() const { // Extracts a signed long long from *this. - // If (x > maximum of signed long long) or (x < minimum of signed long long), - // then the maximum or minimum of signed long long is returned accordingly. + // If (x > maximum of long long) or (x < minimum of long long), + // then the maximum or minimum of long long is returned accordingly. if(exp < static_cast(0)) { - return static_cast(0); + return static_cast(0); } const bool b_neg = isneg(); - unsigned long long val; + boost::ulong_long_type val; if((!b_neg) && (compare(long_long_max()) > 0)) { - return (std::numeric_limits::max)(); + return (std::numeric_limits::max)(); } else if(b_neg && (compare(long_long_min()) < 0)) { - return (std::numeric_limits::min)(); + return (std::numeric_limits::min)(); } else { - // Extract the data into an unsigned long long value. + // Extract the data into an boost::ulong_long_type value. cpp_dec_float xn(extract_integer_part()); if(xn.isneg()) xn.negate(); - val = static_cast(xn.data[0]); + val = static_cast(xn.data[0]); const boost::int32_t imax = (std::min)(static_cast(static_cast(xn.exp) / cpp_dec_float_elem_digits10), static_cast(cpp_dec_float_elem_number - static_cast(1))); for(boost::int32_t i = static_cast(1); i <= imax; i++) { - val *= static_cast(cpp_dec_float_elem_mask); - val += static_cast(xn.data[i]); + val *= static_cast(cpp_dec_float_elem_mask); + val += static_cast(xn.data[i]); } } if (!b_neg) { - return static_cast(val); + return static_cast(val); } else { // This strange expression avoids a hardware trap in the corner case - // that val is the most negative value permitted in long long. + // that val is the most negative value permitted in boost::long_long_type. // See https://svn.boost.org/trac/boost/ticket/9740. // - signed long long sval = static_cast(val - 1); + boost::long_long_type sval = static_cast(val - 1); sval = -sval; --sval; return sval; @@ -1643,43 +1643,43 @@ signed long long cpp_dec_float::extract_signe } template -unsigned long long cpp_dec_float::extract_unsigned_long_long() const +boost::ulong_long_type cpp_dec_float::extract_unsigned_long_long() const { - // Extracts an unsigned long long from *this. - // If x exceeds the maximum of unsigned long long, - // then the maximum of unsigned long long is returned. - // If x is negative, then the unsigned long long cast of - // the signed long long extracted value is returned. + // Extracts an boost::ulong_long_type from *this. + // If x exceeds the maximum of boost::ulong_long_type, + // then the maximum of boost::ulong_long_type is returned. + // If x is negative, then the boost::ulong_long_type cast of + // the long long extracted value is returned. if(isneg()) { - return static_cast(extract_signed_long_long()); + return static_cast(extract_signed_long_long()); } if(exp < static_cast(0)) { - return static_cast(0u); + return static_cast(0u); } const cpp_dec_float xn(extract_integer_part()); - unsigned long long val; + boost::ulong_long_type val; if(xn.compare(ulong_long_max()) > 0) { - return (std::numeric_limits::max)(); + return (std::numeric_limits::max)(); } else { - // Extract the data into an unsigned long long value. - val = static_cast(xn.data[0]); + // Extract the data into an boost::ulong_long_type value. + val = static_cast(xn.data[0]); const boost::int32_t imax = (std::min)(static_cast(static_cast(xn.exp) / cpp_dec_float_elem_digits10), static_cast(cpp_dec_float_elem_number - static_cast(1))); for(boost::int32_t i = static_cast(1); i <= imax; i++) { - val *= static_cast(cpp_dec_float_elem_mask); - val += static_cast(xn.data[i]); + val *= static_cast(cpp_dec_float_elem_mask); + val += static_cast(xn.data[i]); } } @@ -2209,8 +2209,8 @@ cpp_dec_float::cpp_dec_float(const double man template cpp_dec_float& cpp_dec_float::operator= (long double a) { - // Christopher Kormanyos's original code used a cast to long long here, but that fails - // when long double has more digits than a long long. + // Christopher Kormanyos's original code used a cast to boost::long_long_type here, but that fails + // when long double has more digits than a boost::long_long_type. using std::frexp; using std::ldexp; using std::floor; @@ -2259,7 +2259,7 @@ cpp_dec_float& cpp_dec_float -void cpp_dec_float::from_unsigned_long_long(const unsigned long long u) +void cpp_dec_float::from_unsigned_long_long(const boost::ulong_long_type u) { std::fill(data.begin(), data.end(), static_cast(0u)); @@ -2270,14 +2270,14 @@ void cpp_dec_float::from_unsigned_long_long(c std::size_t i =static_cast(0u); - unsigned long long uu = u; + boost::ulong_long_type uu = u; - boost::uint32_t temp[(std::numeric_limits::digits10 / static_cast(cpp_dec_float_elem_digits10)) + 3] = { static_cast(0u) }; + boost::uint32_t temp[(std::numeric_limits::digits10 / static_cast(cpp_dec_float_elem_digits10)) + 3] = { static_cast(0u) }; - while(uu != static_cast(0u)) + while(uu != static_cast(0u)) { - temp[i] = static_cast(uu % static_cast(cpp_dec_float_elem_mask)); - uu = static_cast(uu / static_cast(cpp_dec_float_elem_mask)); + temp[i] = static_cast(uu % static_cast(cpp_dec_float_elem_mask)); + uu = static_cast(uu / static_cast(cpp_dec_float_elem_mask)); ++i; } @@ -2351,7 +2351,7 @@ boost::uint32_t cpp_dec_float::div_loop_n(boo } template -cpp_dec_float cpp_dec_float::pow2(const long long p) +cpp_dec_float cpp_dec_float::pow2(const boost::long_long_type p) { // Create a static const table of p^2 for -128 < p < +128. // Note: The size of this table must be odd-numbered and @@ -2488,24 +2488,24 @@ cpp_dec_float cpp_dec_float(4)), - cpp_dec_float(static_cast(8)), - cpp_dec_float(static_cast(16)), - cpp_dec_float(static_cast(32)), - cpp_dec_float(static_cast(64)), - cpp_dec_float(static_cast(128)), - cpp_dec_float(static_cast(256)), - cpp_dec_float(static_cast(512)), - cpp_dec_float(static_cast(1024)), - cpp_dec_float(static_cast(2048)), - cpp_dec_float(static_cast(4096)), - cpp_dec_float(static_cast(8192)), - cpp_dec_float(static_cast(16384)), - cpp_dec_float(static_cast(32768)), - cpp_dec_float(static_cast(65536)), - cpp_dec_float(static_cast(131072)), - cpp_dec_float(static_cast(262144)), - cpp_dec_float(static_cast(524288)), + cpp_dec_float(static_cast(4)), + cpp_dec_float(static_cast(8)), + cpp_dec_float(static_cast(16)), + cpp_dec_float(static_cast(32)), + cpp_dec_float(static_cast(64)), + cpp_dec_float(static_cast(128)), + cpp_dec_float(static_cast(256)), + cpp_dec_float(static_cast(512)), + cpp_dec_float(static_cast(1024)), + cpp_dec_float(static_cast(2048)), + cpp_dec_float(static_cast(4096)), + cpp_dec_float(static_cast(8192)), + cpp_dec_float(static_cast(16384)), + cpp_dec_float(static_cast(32768)), + cpp_dec_float(static_cast(65536)), + cpp_dec_float(static_cast(131072)), + cpp_dec_float(static_cast(262144)), + cpp_dec_float(static_cast(524288)), cpp_dec_float(static_cast(1uL << 20u)), cpp_dec_float(static_cast(1uL << 21u)), cpp_dec_float(static_cast(1uL << 22u)), @@ -2616,16 +2616,16 @@ cpp_dec_float cpp_dec_float static_cast(-128)) && (p < static_cast(+128))) + if((p > static_cast(-128)) && (p < static_cast(+128))) { return p2_data[static_cast(p + ((p2_data.size() - 1u) / 2u))]; } else { // Compute and return 2^p. - if(p < static_cast(0)) + if(p < static_cast(0)) { - return pow2(static_cast(-p)).calculate_inv(); + return pow2(static_cast(-p)).calculate_inv(); } else { @@ -2659,28 +2659,28 @@ inline void eval_divide(cpp_dec_float& result } template -inline void eval_add(cpp_dec_float& result, const unsigned long long& o) +inline void eval_add(cpp_dec_float& result, const boost::ulong_long_type& o) { result.add_unsigned_long_long(o); } template -inline void eval_subtract(cpp_dec_float& result, const unsigned long long& o) +inline void eval_subtract(cpp_dec_float& result, const boost::ulong_long_type& o) { result.sub_unsigned_long_long(o); } template -inline void eval_multiply(cpp_dec_float& result, const unsigned long long& o) +inline void eval_multiply(cpp_dec_float& result, const boost::ulong_long_type& o) { result.mul_unsigned_long_long(o); } template -inline void eval_divide(cpp_dec_float& result, const unsigned long long& o) +inline void eval_divide(cpp_dec_float& result, const boost::ulong_long_type& o) { result.div_unsigned_long_long(o); } template -inline void eval_add(cpp_dec_float& result, long long o) +inline void eval_add(cpp_dec_float& result, boost::long_long_type o) { if(o < 0) result.sub_unsigned_long_long(boost::multiprecision::detail::unsigned_abs(o)); @@ -2688,7 +2688,7 @@ inline void eval_add(cpp_dec_float& result, l result.add_unsigned_long_long(o); } template -inline void eval_subtract(cpp_dec_float& result, long long o) +inline void eval_subtract(cpp_dec_float& result, boost::long_long_type o) { if(o < 0) result.add_unsigned_long_long(boost::multiprecision::detail::unsigned_abs(o)); @@ -2696,7 +2696,7 @@ inline void eval_subtract(cpp_dec_float& resu result.sub_unsigned_long_long(o); } template -inline void eval_multiply(cpp_dec_float& result, long long o) +inline void eval_multiply(cpp_dec_float& result, boost::long_long_type o) { if(o < 0) { @@ -2707,7 +2707,7 @@ inline void eval_multiply(cpp_dec_float& resu result.mul_unsigned_long_long(o); } template -inline void eval_divide(cpp_dec_float& result, long long o) +inline void eval_divide(cpp_dec_float& result, boost::long_long_type o) { if(o < 0) { @@ -2719,12 +2719,12 @@ inline void eval_divide(cpp_dec_float& result } template -inline void eval_convert_to(unsigned long long* result, const cpp_dec_float& val) +inline void eval_convert_to(boost::ulong_long_type* result, const cpp_dec_float& val) { *result = val.extract_unsigned_long_long(); } template -inline void eval_convert_to(long long* result, const cpp_dec_float& val) +inline void eval_convert_to(boost::long_long_type* result, const cpp_dec_float& val) { *result = val.extract_signed_long_long(); } @@ -2834,18 +2834,18 @@ inline void eval_scalbn(cpp_dec_float& result template inline void eval_ldexp(cpp_dec_float& result, const cpp_dec_float& x, ArgType e) { - const long long the_exp = static_cast(e); + const boost::long_long_type the_exp = static_cast(e); if((the_exp > (std::numeric_limits::max)()) || (the_exp < (std::numeric_limits::min)())) BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Exponent value is out of range."))); result = x; - if ((the_exp > static_cast(-std::numeric_limits::digits)) && (the_exp < static_cast(0))) - result.div_unsigned_long_long(1ULL << static_cast(-the_exp)); - else if((the_exp < static_cast( std::numeric_limits::digits)) && (the_exp > static_cast(0))) + if ((the_exp > static_cast(-std::numeric_limits::digits)) && (the_exp < static_cast(0))) + result.div_unsigned_long_long(1ULL << static_cast(-the_exp)); + else if((the_exp < static_cast( std::numeric_limits::digits)) && (the_exp > static_cast(0))) result.mul_unsigned_long_long(1ULL << the_exp); - else if(the_exp != static_cast(0)) + else if(the_exp != static_cast(0)) result *= cpp_dec_float::pow2(e); } diff --git a/include/boost/multiprecision/cpp_int.hpp b/include/boost/multiprecision/cpp_int.hpp index 311f7c16..26fee765 100644 --- a/include/boost/multiprecision/cpp_int.hpp +++ b/include/boost/multiprecision/cpp_int.hpp @@ -689,7 +689,7 @@ const bool cpp_int_base only -// because some platforms have native integer types longer than long long, "really long long" anyone?? +// because some platforms have native integer types longer than boost::long_long_type, "really boost::long_long_type" anyone?? // template struct trivial_limb_type_imp @@ -704,7 +704,7 @@ struct trivial_limb_type_imp }; template -struct trivial_limb_type : public trivial_limb_type_imp {}; +struct trivial_limb_type : public trivial_limb_type_imp {}; // // Backend for fixed precision signed-magnitude type which will fit entirely inside a "double_limb_type": // @@ -1025,13 +1025,13 @@ public: trivial_tag, mpl::list< signed char, short, int, long, - long long, signed_double_limb_type>, + boost::long_long_type, signed_double_limb_type>, mpl::list >::type signed_types; typedef typename mpl::if_< trivial_tag, mpl::list, + unsigned long, boost::ulong_long_type, double_limb_type>, mpl::list >::type unsigned_types; typedef typename mpl::if_< diff --git a/include/boost/multiprecision/cpp_int/checked.hpp b/include/boost/multiprecision/cpp_int/checked.hpp index bf3bc650..cafe50ea 100644 --- a/include/boost/multiprecision/cpp_int/checked.hpp +++ b/include/boost/multiprecision/cpp_int/checked.hpp @@ -128,7 +128,7 @@ inline A checked_divide(A a, A b, const mpl::int_&) } template -inline A checked_left_shift(A a, unsigned long long shift, const mpl::int_&) +inline A checked_left_shift(A a, boost::ulong_long_type shift, const mpl::int_&) { if(a && shift) { @@ -138,7 +138,7 @@ inline A checked_left_shift(A a, unsigned long long shift, const mpl::int_ -inline A checked_left_shift(A a, unsigned long long shift, const mpl::int_&) +inline A checked_left_shift(A a, boost::ulong_long_type shift, const mpl::int_&) { return (shift >= sizeof(A) * CHAR_BIT) ? 0 : a << shift; } diff --git a/include/boost/multiprecision/cpp_int/cpp_int_config.hpp b/include/boost/multiprecision/cpp_int/cpp_int_config.hpp index 0b8b33d3..eb88f3da 100644 --- a/include/boost/multiprecision/cpp_int/cpp_int_config.hpp +++ b/include/boost/multiprecision/cpp_int/cpp_int_config.hpp @@ -19,7 +19,7 @@ namespace detail{ // // These traits calculate the largest type in the list -// [unsigned] long long, long, int, which has the specified number +// [unsigned] boost::long_long_type, long, int, which has the specified number // of bits. Note that intN_t and boost::int_t find the first // member of the above list, not the last. We want the last in the // list to ensure that mixed arithmetic operations are as efficient @@ -29,8 +29,8 @@ template struct largest_signed_type { typedef typename mpl::if_c< - 1 + std::numeric_limits::digits == N, - long long, + 1 + std::numeric_limits::digits == N, + boost::long_long_type, typename mpl::if_c< 1 + std::numeric_limits::digits == N, long, @@ -47,8 +47,8 @@ template struct largest_unsigned_type { typedef typename mpl::if_c< - std::numeric_limits::digits == N, - unsigned long long, + std::numeric_limits::digits == N, + boost::ulong_long_type, typename mpl::if_c< std::numeric_limits::digits == N, unsigned long, diff --git a/include/boost/multiprecision/detail/bitscan.hpp b/include/boost/multiprecision/detail/bitscan.hpp index 40602a93..ce1cdc8d 100644 --- a/include/boost/multiprecision/detail/bitscan.hpp +++ b/include/boost/multiprecision/detail/bitscan.hpp @@ -124,7 +124,7 @@ BOOST_FORCEINLINE unsigned find_lsb(unsigned long mask, mpl::int_<2> const&) { return __builtin_ctzl(mask); } -BOOST_FORCEINLINE unsigned find_lsb(unsigned long long mask, mpl::int_<3> const&) +BOOST_FORCEINLINE unsigned find_lsb(boost::ulong_long_type mask, mpl::int_<3> const&) { return __builtin_ctzll(mask); } @@ -136,9 +136,9 @@ BOOST_FORCEINLINE unsigned find_msb(unsigned long mask, mpl::int_<2> const&) { return sizeof(unsigned long) * CHAR_BIT - 1 - __builtin_clzl(mask); } -BOOST_FORCEINLINE unsigned find_msb(unsigned long long mask, mpl::int_<3> const&) +BOOST_FORCEINLINE unsigned find_msb(boost::ulong_long_type mask, mpl::int_<3> const&) { - return sizeof(unsigned long long) * CHAR_BIT - 1 - __builtin_clzll(mask); + return sizeof(boost::ulong_long_type) * CHAR_BIT - 1 - __builtin_clzll(mask); } template @@ -152,7 +152,7 @@ BOOST_FORCEINLINE unsigned find_lsb(Unsigned mask) sizeof(Unsigned) <= sizeof(unsigned long), mpl::int_<2>, typename mpl::if_c< - sizeof(Unsigned) <= sizeof(unsigned long long), + sizeof(Unsigned) <= sizeof(boost::ulong_long_type), mpl::int_<3>, mpl::int_<0> >::type @@ -171,7 +171,7 @@ BOOST_FORCEINLINE unsigned find_msb(Unsigned mask) sizeof(Unsigned) <= sizeof(unsigned long), mpl::int_<2>, typename mpl::if_c< - sizeof(Unsigned) <= sizeof(unsigned long long), + sizeof(Unsigned) <= sizeof(boost::ulong_long_type), mpl::int_<3>, mpl::int_<0> >::type diff --git a/include/boost/multiprecision/detail/default_ops.hpp b/include/boost/multiprecision/detail/default_ops.hpp index bf51a582..01fbe181 100644 --- a/include/boost/multiprecision/detail/default_ops.hpp +++ b/include/boost/multiprecision/detail/default_ops.hpp @@ -1219,7 +1219,7 @@ inline typename B::exponent_type eval_ilogb(const B& val) template inline void eval_logb(B& result, const B& val) { - typedef typename boost::mpl::if_c::value, long long, boost::intmax_t>::type max_t; + typedef typename boost::mpl::if_c::value, boost::long_long_type, boost::intmax_t>::type max_t; result = static_cast(eval_ilogb(val)); } template @@ -1436,29 +1436,29 @@ inline long ltrunc(const number& v) } #ifndef BOOST_NO_LONG_LONG template -inline long long lltrunc(const detail::expression& v, const Policy& pol) +inline boost::long_long_type lltrunc(const detail::expression& v, const Policy& pol) { typedef typename detail::expression::result_type number_type; number_type r = trunc(v, pol); - if((r > (std::numeric_limits::max)()) || r < (std::numeric_limits::min)() || !(boost::math::isfinite)(v)) + if((r > (std::numeric_limits::max)()) || r < (std::numeric_limits::min)() || !(boost::math::isfinite)(v)) return boost::math::policies::raise_rounding_error("boost::multiprecision::lltrunc<%1%>(%1%)", 0, number_type(v), 0LL, pol); - return r.template convert_to(); + return r.template convert_to(); } template -inline long long lltrunc(const detail::expression& v) +inline boost::long_long_type lltrunc(const detail::expression& v) { return lltrunc(v, boost::math::policies::policy<>()); } template -inline long long lltrunc(const number& v, const Policy& pol) +inline boost::long_long_type lltrunc(const number& v, const Policy& pol) { number r = trunc(v, pol); - if((r > (std::numeric_limits::max)()) || r < (std::numeric_limits::min)() || !(boost::math::isfinite)(v)) + if((r > (std::numeric_limits::max)()) || r < (std::numeric_limits::min)() || !(boost::math::isfinite)(v)) return boost::math::policies::raise_rounding_error("boost::multiprecision::lltrunc<%1%>(%1%)", 0, v, 0LL, pol); - return r.template convert_to(); + return r.template convert_to(); } template -inline long long lltrunc(const number& v) +inline boost::long_long_type lltrunc(const number& v) { return lltrunc(v, boost::math::policies::policy<>()); } @@ -1534,29 +1534,29 @@ inline long lround(const number& v) } #ifndef BOOST_NO_LONG_LONG template -inline long long llround(const detail::expression& v, const Policy& pol) +inline boost::long_long_type llround(const detail::expression& v, const Policy& pol) { typedef typename detail::expression::result_type number_type; number_type r = round(v, pol); - if((r > (std::numeric_limits::max)()) || r < (std::numeric_limits::min)() || !(boost::math::isfinite)(v)) + if((r > (std::numeric_limits::max)()) || r < (std::numeric_limits::min)() || !(boost::math::isfinite)(v)) return boost::math::policies::raise_rounding_error("boost::multiprecision::iround<%1%>(%1%)", 0, number_type(v), 0LL, pol); - return r.template convert_to(); + return r.template convert_to(); } template -inline long long llround(const detail::expression& v) +inline boost::long_long_type llround(const detail::expression& v) { return llround(v, boost::math::policies::policy<>()); } template -inline long long llround(const number& v, const Policy& pol) +inline boost::long_long_type llround(const number& v, const Policy& pol) { number r = round(v, pol); - if((r > (std::numeric_limits::max)()) || r < (std::numeric_limits::min)() || !(boost::math::isfinite)(v)) + if((r > (std::numeric_limits::max)()) || r < (std::numeric_limits::min)() || !(boost::math::isfinite)(v)) return boost::math::policies::raise_rounding_error("boost::multiprecision::iround<%1%>(%1%)", 0, v, 0LL, pol); - return r.template convert_to(); + return r.template convert_to(); } template -inline long long llround(const number& v) +inline boost::long_long_type llround(const number& v) { return llround(v, boost::math::policies::policy<>()); } @@ -1612,7 +1612,7 @@ frexp(const detail::expression& v, long* pint) return BOOST_MP_MOVE(frexp(static_cast(v), pint)); } template -inline typename enable_if_c::value == number_kind_floating_point, number >::type frexp(const number& v, long long* pint) +inline typename enable_if_c::value == number_kind_floating_point, number >::type frexp(const number& v, boost::long_long_type* pint) { using default_ops::eval_frexp; number result; @@ -1621,7 +1621,7 @@ inline typename enable_if_c::value == number_kind_floating_po } template inline typename enable_if_c::result_type>::value == number_kind_floating_point, typename detail::expression::result_type>::type -frexp(const detail::expression& v, long long* pint) +frexp(const detail::expression& v, boost::long_long_type* pint) { typedef typename detail::expression::result_type number_type; return BOOST_MP_MOVE(frexp(static_cast(v), pint)); @@ -2104,8 +2104,8 @@ HETERO_BINARY_OP_FUNCTOR_B(ldexp, int, number_kind_floating_point) //HETERO_BINARY_OP_FUNCTOR_B(frexp, int*, number_kind_floating_point) HETERO_BINARY_OP_FUNCTOR_B(ldexp, long, number_kind_floating_point) //HETERO_BINARY_OP_FUNCTOR_B(frexp, long*, number_kind_floating_point) -HETERO_BINARY_OP_FUNCTOR_B(ldexp, long long, number_kind_floating_point) -//HETERO_BINARY_OP_FUNCTOR_B(frexp, long long*, number_kind_floating_point) +HETERO_BINARY_OP_FUNCTOR_B(ldexp, boost::long_long_type, number_kind_floating_point) +//HETERO_BINARY_OP_FUNCTOR_B(frexp, boost::long_long_type*, number_kind_floating_point) BINARY_OP_FUNCTOR(pow, number_kind_floating_point) BINARY_OP_FUNCTOR(fmod, number_kind_floating_point) BINARY_OP_FUNCTOR(atan2, number_kind_floating_point) @@ -2114,7 +2114,7 @@ UNARY_OP_FUNCTOR(logb, number_kind_floating_point) HETERO_BINARY_OP_FUNCTOR(scalbn, short, number_kind_floating_point) HETERO_BINARY_OP_FUNCTOR_B(scalbn, int, number_kind_floating_point) HETERO_BINARY_OP_FUNCTOR_B(scalbn, long, number_kind_floating_point) -HETERO_BINARY_OP_FUNCTOR_B(scalbn, long long, number_kind_floating_point) +HETERO_BINARY_OP_FUNCTOR_B(scalbn, boost::long_long_type, number_kind_floating_point) // // Integer functions: diff --git a/include/boost/multiprecision/detail/generic_interconvert.hpp b/include/boost/multiprecision/detail/generic_interconvert.hpp index 690723be..b261d81e 100644 --- a/include/boost/multiprecision/detail/generic_interconvert.hpp +++ b/include/boost/multiprecision/detail/generic_interconvert.hpp @@ -392,7 +392,7 @@ template void generic_interconvert_float2rational(To& to, const From& from, const mpl::int_<2>& /*radix*/) { typedef typename mpl::front::type ui_type; - static const int shift = std::numeric_limits::digits; + static const int shift = std::numeric_limits::digits; typename From::exponent_type e; typename component_type >::type num, denom; number val(from); @@ -401,7 +401,7 @@ void generic_interconvert_float2rational(To& to, const From& from, const mpl::in { val = ldexp(val, shift); e -= shift; - long long ll = boost::math::lltrunc(val); + boost::long_long_type ll = boost::math::lltrunc(val); val -= ll; num <<= shift; num += ll; @@ -430,7 +430,7 @@ void generic_interconvert_float2rational(To& to, const From& from, const mpl::in val = scalbn(val, -e); while(val) { - long long ll = boost::math::lltrunc(val); + boost::long_long_type ll = boost::math::lltrunc(val); val -= ll; val = scalbn(val, 1); num *= Radix; diff --git a/include/boost/multiprecision/detail/number_base.hpp b/include/boost/multiprecision/detail/number_base.hpp index 09c86e6c..d08b2a6e 100644 --- a/include/boost/multiprecision/detail/number_base.hpp +++ b/include/boost/multiprecision/detail/number_base.hpp @@ -72,13 +72,13 @@ struct is_compatible_arithmetic_type namespace detail{ // -// Workaround for missing abs(long long) and abs(__int128) on some compilers: +// Workaround for missing abs(boost::long_long_type) and abs(__int128) on some compilers: // template BOOST_CONSTEXPR typename enable_if_c<(is_signed::value || is_floating_point::value), T>::type abs(T t) BOOST_NOEXCEPT { // This strange expression avoids a hardware trap in the corner case - // that val is the most negative value permitted in long long. + // that val is the most negative value permitted in boost::long_long_type. // See https://svn.boost.org/trac/boost/ticket/9740. return t < 0 ? T(1u) + T(-(t + 1)) : t; } @@ -94,7 +94,7 @@ template BOOST_CONSTEXPR typename enable_if_c<(is_signed::value || is_floating_point::value), typename make_unsigned::type>::type unsigned_abs(T t) BOOST_NOEXCEPT { // This strange expression avoids a hardware trap in the corner case - // that val is the most negative value permitted in long long. + // that val is the most negative value permitted in boost::long_long_type. // See https://svn.boost.org/trac/boost/ticket/9740. return t < 0 ? static_cast::type>(1u) + static_cast::type>(-(t + 1)) : static_cast::type>(t); } diff --git a/include/boost/multiprecision/float128.hpp b/include/boost/multiprecision/float128.hpp index 6e2958e0..d736f8ae 100644 --- a/include/boost/multiprecision/float128.hpp +++ b/include/boost/multiprecision/float128.hpp @@ -127,9 +127,9 @@ namespace backends{ struct float128_backend { - typedef mpl::list signed_types; + typedef mpl::list signed_types; typedef mpl::list unsigned_types; + unsigned int, unsigned long, boost::ulong_long_type> unsigned_types; typedef mpl::list float_types; typedef int exponent_type; diff --git a/include/boost/multiprecision/gmp.hpp b/include/boost/multiprecision/gmp.hpp index 0ab8346a..097c298e 100644 --- a/include/boost/multiprecision/gmp.hpp +++ b/include/boost/multiprecision/gmp.hpp @@ -60,8 +60,8 @@ template struct gmp_float_imp { #ifdef BOOST_HAS_LONG_LONG - typedef mpl::list signed_types; - typedef mpl::list unsigned_types; + typedef mpl::list signed_types; + typedef mpl::list unsigned_types; #else typedef mpl::list signed_types; typedef mpl::list unsigned_types; @@ -108,16 +108,17 @@ struct gmp_float_imp #ifdef BOOST_HAS_LONG_LONG #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX) - gmp_float_imp& operator = (unsigned long long i) + gmp_float_imp& operator = (boost::ulong_long_type i) { *this = static_cast(i); + return *this; } #else - gmp_float_imp& operator = (unsigned long long i) + gmp_float_imp& operator = (boost::ulong_long_type i) { if(m_data[0]._mp_d == 0) mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - unsigned long long 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; mpf_t t; mpf_init2(t, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); @@ -135,12 +136,12 @@ struct gmp_float_imp return *this; } #endif - gmp_float_imp& operator = (long long i) + gmp_float_imp& operator = (boost::long_long_type i) { if(m_data[0]._mp_d == 0) mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); bool neg = i < 0; - *this = static_cast(boost::multiprecision::detail::unsigned_abs(i)); + *this = static_cast(boost::multiprecision::detail::unsigned_abs(i)); if(neg) mpf_neg(m_data, m_data); return *this; @@ -858,13 +859,13 @@ inline void eval_convert_to(double* result, const gmp_float& val) BOOS } #ifdef BOOST_HAS_LONG_LONG template -inline void eval_convert_to(long long* result, const gmp_float& val) +inline void eval_convert_to(boost::long_long_type* result, const gmp_float& val) { gmp_float t(val); if(eval_get_sign(t) < 0) t.negate(); - long digits = std::numeric_limits::digits - std::numeric_limits::digits; + long digits = std::numeric_limits::digits - std::numeric_limits::digits; if(digits > 0) mpf_div_2exp(t.data(), t.data(), digits); @@ -872,9 +873,9 @@ inline void eval_convert_to(long long* result, const gmp_float& val) if(!mpf_fits_slong_p(t.data())) { if(eval_get_sign(val) < 0) - *result = (std::numeric_limits::min)(); + *result = (std::numeric_limits::min)(); else - *result = (std::numeric_limits::max)(); + *result = (std::numeric_limits::max)(); return; }; @@ -893,18 +894,18 @@ inline void eval_convert_to(long long* result, const gmp_float& val) *result = -*result; } template -inline void eval_convert_to(unsigned long long* result, const gmp_float& val) +inline void eval_convert_to(boost::ulong_long_type* result, const gmp_float& val) { gmp_float t(val); - long digits = std::numeric_limits::digits - std::numeric_limits::digits; + long digits = std::numeric_limits::digits - std::numeric_limits::digits; if(digits > 0) mpf_div_2exp(t.data(), t.data(), digits); if(!mpf_fits_ulong_p(t.data())) { - *result = (std::numeric_limits::max)(); + *result = (std::numeric_limits::max)(); return; } @@ -985,8 +986,8 @@ inline void eval_frexp(gmp_float& result, const gmp_float& v struct gmp_int { #ifdef BOOST_HAS_LONG_LONG - typedef mpl::list signed_types; - typedef mpl::list unsigned_types; + typedef mpl::list signed_types; + typedef mpl::list unsigned_types; #else typedef mpl::list signed_types; typedef mpl::list unsigned_types; @@ -1048,16 +1049,17 @@ struct gmp_int #endif #ifdef BOOST_HAS_LONG_LONG #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX) - gmp_int& operator = (unsigned long long i) + gmp_int& operator = (boost::ulong_long_type i) { *this = static_cast(i); + return *this; } #else - gmp_int& operator = (unsigned long long i) + gmp_int& operator = (boost::ulong_long_type i) { if(m_data[0]._mp_d == 0) mpz_init(this->m_data); - unsigned long long 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; mpz_t t; mpz_set_ui(m_data, 0); @@ -1075,7 +1077,7 @@ struct gmp_int return *this; } #endif - gmp_int& operator = (long long i) + gmp_int& operator = (boost::long_long_type i) { if(m_data[0]._mp_d == 0) mpz_init(this->m_data); @@ -1736,8 +1738,8 @@ void eval_add(gmp_rational& t, const gmp_rational& o); struct gmp_rational { #ifdef BOOST_HAS_LONG_LONG - typedef mpl::list signed_types; - typedef mpl::list unsigned_types; + typedef mpl::list signed_types; + typedef mpl::list unsigned_types; #else typedef mpl::list signed_types; typedef mpl::list unsigned_types; @@ -1793,12 +1795,13 @@ struct gmp_rational #endif #ifdef BOOST_HAS_LONG_LONG #if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX) - gmp_rational& operator = (unsigned long long i) + gmp_rational& operator = (boost::ulong_long_type i) { *this = static_cast(i); + return *this; } #else - gmp_rational& operator = (unsigned long long i) + gmp_rational& operator = (boost::ulong_long_type i) { if(m_data[0]._mp_den._mp_d == 0) mpq_init(m_data); @@ -1807,7 +1810,7 @@ struct gmp_rational mpq_set_z(m_data, zi.data()); return *this; } - gmp_rational& operator = (long long i) + gmp_rational& operator = (boost::long_long_type i) { if(m_data[0]._mp_den._mp_d == 0) mpq_init(m_data); diff --git a/include/boost/multiprecision/integer.hpp b/include/boost/multiprecision/integer.hpp index 4432f1e9..e4c8bf8b 100644 --- a/include/boost/multiprecision/integer.hpp +++ b/include/boost/multiprecision/integer.hpp @@ -48,17 +48,17 @@ namespace detail{ // // Figure out the kind of integer that has twice as many bits as some builtin // integer type I. Use a native type if we can (including types which may not -// be recognised by boost::int_t because they're larger than long long), +// be recognised by boost::int_t because they're larger than boost::long_long_type), // otherwise synthesize a cpp_int to do the job. // template struct double_integer { static const unsigned int_t_digits = - 2 * sizeof(I) <= sizeof(long long) ? std::numeric_limits::digits * 2 : 1; + 2 * sizeof(I) <= sizeof(boost::long_long_type) ? std::numeric_limits::digits * 2 : 1; typedef typename mpl::if_c< - 2 * sizeof(I) <= sizeof(long long), + 2 * sizeof(I) <= sizeof(boost::long_long_type), typename mpl::if_c< is_signed::value, typename boost::int_t::least, diff --git a/include/boost/multiprecision/mpfi.hpp b/include/boost/multiprecision/mpfi.hpp index 68b77797..7dc2b9d7 100644 --- a/include/boost/multiprecision/mpfi.hpp +++ b/include/boost/multiprecision/mpfi.hpp @@ -56,8 +56,8 @@ template struct mpfi_float_imp { #ifdef BOOST_HAS_LONG_LONG - typedef mpl::list signed_types; - typedef mpl::list unsigned_types; + typedef mpl::list signed_types; + typedef mpl::list unsigned_types; #else typedef mpl::list signed_types; typedef mpl::list unsigned_types; @@ -104,7 +104,7 @@ struct mpfi_float_imp #endif #ifdef BOOST_HAS_LONG_LONG #ifdef _MPFR_H_HAVE_INTMAX_T - mpfi_float_imp& operator = (unsigned long long i) + mpfi_float_imp& operator = (boost::ulong_long_type i) { if(m_data[0].left._mpfr_d == 0) mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); @@ -112,7 +112,7 @@ struct mpfi_float_imp mpfr_set_uj(right_data(), i, GMP_RNDU); return *this; } - mpfi_float_imp& operator = (long long i) + mpfi_float_imp& operator = (boost::long_long_type i) { if(m_data[0].left._mpfr_d == 0) mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); @@ -121,14 +121,14 @@ struct mpfi_float_imp return *this; } #else - mpfi_float_imp& operator = (unsigned long long i) + mpfi_float_imp& operator = (boost::ulong_long_type i) { if(m_data[0].left._mpfr_d == 0) mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - unsigned long long 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)))); + mpfi_init2(t, (std::max)(static_cast(std::numeric_limits::digits), static_cast(multiprecision::detail::digits10_2_2(digits10)))); mpfi_set_ui(m_data, 0); while(i) { @@ -142,7 +142,7 @@ struct mpfi_float_imp mpfi_clear(t); return *this; } - mpfi_float_imp& operator = (long long i) + mpfi_float_imp& operator = (boost::long_long_type i) { if(m_data[0].left._mpfr_d == 0) mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); @@ -738,14 +738,14 @@ inline void eval_convert_to(long* result, const mpfi_float_backend& va } #ifdef _MPFR_H_HAVE_INTMAX_T template -inline void eval_convert_to(unsigned long long* result, const mpfi_float_backend& val) +inline void eval_convert_to(boost::ulong_long_type* result, const mpfi_float_backend& val) { mpfr_float_backend t; mpfi_mid(t.data(), val.data()); eval_convert_to(result, t); } template -inline void eval_convert_to(long long* result, const mpfi_float_backend& val) +inline void eval_convert_to(boost::long_long_type* result, const mpfi_float_backend& val) { mpfr_float_backend t; mpfi_mid(t.data(), val.data()); diff --git a/include/boost/multiprecision/mpfr.hpp b/include/boost/multiprecision/mpfr.hpp index d9327e28..02e13a02 100644 --- a/include/boost/multiprecision/mpfr.hpp +++ b/include/boost/multiprecision/mpfr.hpp @@ -64,8 +64,8 @@ template struct mpfr_float_imp { #ifdef BOOST_HAS_LONG_LONG - typedef mpl::list signed_types; - typedef mpl::list unsigned_types; + typedef mpl::list signed_types; + typedef mpl::list unsigned_types; #else typedef mpl::list signed_types; typedef mpl::list unsigned_types; @@ -112,14 +112,14 @@ struct mpfr_float_imp #endif #ifdef BOOST_HAS_LONG_LONG #ifdef _MPFR_H_HAVE_INTMAX_T - mpfr_float_imp& operator = (unsigned long long i) + mpfr_float_imp& operator = (boost::ulong_long_type i) { if(m_data[0]._mpfr_d == 0) mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); mpfr_set_uj(m_data, i, GMP_RNDN); return *this; } - mpfr_float_imp& operator = (long long i) + mpfr_float_imp& operator = (boost::long_long_type i) { if(m_data[0]._mpfr_d == 0) mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); @@ -127,14 +127,14 @@ struct mpfr_float_imp return *this; } #else - mpfr_float_imp& operator = (unsigned long long i) + mpfr_float_imp& operator = (boost::ulong_long_type i) { if(m_data[0]._mpfr_d == 0) mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); - unsigned long long 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)))); + mpfr_init2(t, (std::max)(static_cast(std::numeric_limits::digits), static_cast(multiprecision::detail::digits10_2_2(digits10)))); mpfr_set_ui(m_data, 0, GMP_RNDN); while(i) { @@ -148,7 +148,7 @@ struct mpfr_float_imp mpfr_clear(t); return *this; } - mpfr_float_imp& operator = (long long i) + mpfr_float_imp& operator = (boost::long_long_type i) { if(m_data[0]._mpfr_d == 0) mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision())); @@ -371,8 +371,8 @@ template struct mpfr_float_imp { #ifdef BOOST_HAS_LONG_LONG - typedef mpl::list signed_types; - typedef mpl::list unsigned_types; + typedef mpl::list signed_types; + typedef mpl::list unsigned_types; #else typedef mpl::list signed_types; typedef mpl::list unsigned_types; @@ -406,20 +406,20 @@ struct mpfr_float_imp } #ifdef BOOST_HAS_LONG_LONG #ifdef _MPFR_H_HAVE_INTMAX_T - mpfr_float_imp& operator = (unsigned long long i) + mpfr_float_imp& operator = (boost::ulong_long_type i) { mpfr_set_uj(m_data, i, GMP_RNDN); return *this; } - mpfr_float_imp& operator = (long long i) + mpfr_float_imp& operator = (boost::long_long_type i) { mpfr_set_sj(m_data, i, GMP_RNDN); return *this; } #else - mpfr_float_imp& operator = (unsigned long long i) + mpfr_float_imp& operator = (boost::ulong_long_type i) { - unsigned long long 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]; @@ -437,7 +437,7 @@ struct mpfr_float_imp } return *this; } - mpfr_float_imp& operator = (long long i) + mpfr_float_imp& operator = (boost::long_long_type i) { bool neg = i < 0; *this = boost::multiprecision::detail::unsigned_abs(i); @@ -1206,7 +1206,7 @@ inline void eval_convert_to(long* result, const mpfr_float_backend -inline void eval_convert_to(unsigned long long* result, const mpfr_float_backend& val) +inline void eval_convert_to(boost::ulong_long_type* result, const mpfr_float_backend& val) { if(mpfr_nan_p(val.data())) { @@ -1215,7 +1215,7 @@ inline void eval_convert_to(unsigned long long* result, const mpfr_float_backend *result = mpfr_get_uj(val.data(), GMP_RNDZ); } template -inline void eval_convert_to(long long* result, const mpfr_float_backend& val) +inline void eval_convert_to(boost::long_long_type* result, const mpfr_float_backend& val) { if(mpfr_nan_p(val.data())) { diff --git a/include/boost/multiprecision/tommath.hpp b/include/boost/multiprecision/tommath.hpp index 8abee83c..90b1b788 100644 --- a/include/boost/multiprecision/tommath.hpp +++ b/include/boost/multiprecision/tommath.hpp @@ -38,8 +38,8 @@ void eval_add(tommath_int& t, const tommath_int& o); struct tommath_int { - typedef mpl::list signed_types; - typedef mpl::list unsigned_types; + typedef mpl::list signed_types; + typedef mpl::list unsigned_types; typedef mpl::list float_types; tommath_int() @@ -70,11 +70,11 @@ struct tommath_int detail::check_tommath_result(mp_copy(const_cast< ::mp_int*>(&o.m_data), &m_data)); return *this; } - tommath_int& operator = (unsigned long long i) + tommath_int& operator = (boost::ulong_long_type i) { if(m_data.dp == 0) detail::check_tommath_result(mp_init(&m_data)); - unsigned long long mask = ((1uLL << std::numeric_limits::digits) - 1); + boost::ulong_long_type mask = ((1uLL << std::numeric_limits::digits) - 1); unsigned shift = 0; ::mp_int t; detail::check_tommath_result(mp_init(&t)); @@ -91,7 +91,7 @@ struct tommath_int mp_clear(&t); return *this; } - tommath_int& operator = (long long i) + tommath_int& operator = (boost::long_long_type i) { if(m_data.dp == 0) detail::check_tommath_result(mp_init(&m_data)); @@ -222,7 +222,7 @@ struct tommath_int unsigned shift = radix == 8 ? 3 : 4; unsigned block_count = DIGIT_BIT / shift; unsigned block_shift = shift * block_count; - unsigned long long val, block; + boost::ulong_long_type val, block; while(*s) { block = 0; @@ -536,7 +536,7 @@ inline void eval_complement(tommath_int& result, const tommath_int& u) // Create a mask providing the extra bits we need and add to result: tommath_int mask; - mask = static_cast((1u << padding) - 1); + mask = static_cast((1u << padding) - 1); eval_left_shift(mask, shift); add(result, mask); } From f5f6a1fd17360ed53f08177a5cb1392ae050dfbe Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Fri, 3 Apr 2015 09:35:58 +0100 Subject: [PATCH 04/33] Fix NaN comparisons. Add tests to verify comparisons of NaN's are unordered. Fix operators to check for unordered comparisons. Fixes: https://svn.boost.org/trac/boost/ticket/11159 --- .../multiprecision/detail/number_compare.hpp | 73 ++++++++++++++++++- test/test_arithmetic.hpp | 65 +++++++++++++++++ 2 files changed, 135 insertions(+), 3 deletions(-) diff --git a/include/boost/multiprecision/detail/number_compare.hpp b/include/boost/multiprecision/detail/number_compare.hpp index d1606ad7..bddbf4a1 100644 --- a/include/boost/multiprecision/detail/number_compare.hpp +++ b/include/boost/multiprecision/detail/number_compare.hpp @@ -91,12 +91,42 @@ template , number > : public mpl::bool_, number >::value> {}; +template +inline BOOST_CONSTEXPR typename boost::enable_if_c::value != number_kind_floating_point, bool>::type is_unordered_value(const number&) +{ + return false; +} +template +inline BOOST_CONSTEXPR typename boost::enable_if_c::value == number_kind_floating_point, bool>::type is_unordered_value(const number& a) +{ + using default_ops::eval_fpclassify; + return eval_fpclassify(a.backend()) == FP_NAN; +} + +template +inline BOOST_CONSTEXPR typename boost::enable_if_c::value != number_kind_floating_point, bool>::type is_unordered_value(const Arithmetic&) +{ + return false; +} +template +inline BOOST_CONSTEXPR typename boost::enable_if_c::value == number_kind_floating_point, bool>::type is_unordered_value(const Arithmetic& a) +{ + return (boost::math::isnan)(a); +} + +template +inline BOOST_CONSTEXPR bool is_unordered_comparison(const T& a, const U& b) +{ + return is_unordered_value(a) || is_unordered_value(b); +} + } template inline bool operator == (const number& a, const number& b) { using default_ops::eval_eq; + if(detail::is_unordered_comparison(a, b)) return false; return eval_eq(a.backend(), b.backend()); } template @@ -104,6 +134,7 @@ inline typename enable_if_c& a, const Arithmetic& b) { using default_ops::eval_eq; + if(detail::is_unordered_comparison(a, b)) return false; return eval_eq(a.backend(), number::canonical_value(b)); } template @@ -111,6 +142,7 @@ inline typename enable_if_c& b) { using default_ops::eval_eq; + if(detail::is_unordered_comparison(a, b)) return false; return eval_eq(b.backend(), number::canonical_value(a)); } template @@ -120,6 +152,7 @@ inline typename enable_if_c::result_type result_type; using default_ops::eval_eq; result_type t(b); + if(detail::is_unordered_comparison(a, t)) return false; return eval_eq(t.backend(), result_type::canonical_value(a)); } template @@ -129,6 +162,7 @@ inline typename enable_if_c::result_type result_type; using default_ops::eval_eq; result_type t(a); + if(detail::is_unordered_comparison(t, b)) return false; return eval_eq(t.backend(), result_type::canonical_value(b)); } template @@ -138,6 +172,7 @@ inline typename enable_if::result_type t(a); typename detail::expression::result_type t2(b); + if(detail::is_unordered_comparison(t, t2)) return false; return eval_eq(t.backend(), t2.backend()); } @@ -145,6 +180,7 @@ template & a, const number& b) { using default_ops::eval_eq; + if(detail::is_unordered_comparison(a, b)) return true; return !eval_eq(a.backend(), b.backend()); } template @@ -152,6 +188,7 @@ inline typename enable_if_c& a, const Arithmetic& b) { using default_ops::eval_eq; + if(detail::is_unordered_comparison(a, b)) return true; return !eval_eq(a.backend(), number::canonical_value(b)); } template @@ -159,6 +196,7 @@ inline typename enable_if_c& b) { using default_ops::eval_eq; + if(detail::is_unordered_comparison(a, b)) return true; return !eval_eq(b.backend(), number::canonical_value(a)); } template @@ -168,6 +206,7 @@ inline typename enable_if_c::result_type result_type; using default_ops::eval_eq; result_type t(b); + if(detail::is_unordered_comparison(a, t)) return true; return !eval_eq(t.backend(), result_type::canonical_value(a)); } template @@ -177,6 +216,7 @@ inline typename enable_if_c::result_type result_type; using default_ops::eval_eq; result_type t(a); + if(detail::is_unordered_comparison(t, b)) return true; return !eval_eq(t.backend(), result_type::canonical_value(b)); } template @@ -186,6 +226,7 @@ inline typename enable_if::result_type t(a); typename detail::expression::result_type t2(b); + if(detail::is_unordered_comparison(t, t2)) return true; return !eval_eq(t.backend(), t2.backend()); } @@ -193,6 +234,7 @@ template & a, const number& b) { using default_ops::eval_lt; + if(detail::is_unordered_comparison(a, b)) return false; return eval_lt(a.backend(), b.backend()); } template @@ -200,6 +242,7 @@ inline typename enable_if_c& a, const Arithmetic& b) { using default_ops::eval_lt; + if(detail::is_unordered_comparison(a, b)) return false; return eval_lt(a.backend(), number::canonical_value(b)); } template @@ -207,6 +250,7 @@ inline typename enable_if_c& b) { using default_ops::eval_gt; + if(detail::is_unordered_comparison(a, b)) return false; return eval_gt(b.backend(), number::canonical_value(a)); } template @@ -216,6 +260,7 @@ inline typename enable_if_c::result_type result_type; using default_ops::eval_gt; result_type t(b); + if(detail::is_unordered_comparison(a, t)) return false; return eval_gt(t.backend(), result_type::canonical_value(a)); } template @@ -225,6 +270,7 @@ inline typename enable_if_c::result_type result_type; using default_ops::eval_lt; result_type t(a); + if(detail::is_unordered_comparison(t, b)) return false; return eval_lt(t.backend(), result_type::canonical_value(b)); } template @@ -234,6 +280,7 @@ inline typename enable_if::result_type t(a); typename detail::expression::result_type t2(b); + if(detail::is_unordered_comparison(t, t2)) return false; return eval_lt(t.backend(), t2.backend()); } @@ -241,6 +288,7 @@ template (const number& a, const number& b) { using default_ops::eval_gt; + if(detail::is_unordered_comparison(a, b)) return false; return eval_gt(a.backend(), b.backend()); } template @@ -248,6 +296,7 @@ inline typename enable_if_c (const number& a, const Arithmetic& b) { using default_ops::eval_gt; + if(detail::is_unordered_comparison(a, b)) return false; return eval_gt(a.backend(), number::canonical_value(b)); } template @@ -255,6 +304,7 @@ inline typename enable_if_c (const Arithmetic& a, const number& b) { using default_ops::eval_lt; + if(detail::is_unordered_comparison(a, b)) return false; return eval_lt(b.backend(), number::canonical_value(a)); } template @@ -264,7 +314,8 @@ inline typename enable_if_c::result_type result_type; using default_ops::eval_lt; result_type t(b); - return eval_lt(t.backend(), result_type::canonical_value(a)); + if(detail::is_unordered_comparison(a, t)) return false; + return a > t; } template inline typename enable_if_c::result_type, Arithmetic>::value, bool>::type @@ -273,7 +324,8 @@ inline typename enable_if_c::result_type result_type; using default_ops::eval_gt; result_type t(a); - return eval_gt(t.backend(), result_type::canonical_value(b)); + if(detail::is_unordered_comparison(t, b)) return false; + return t > b; } template inline typename enable_if::result_type, typename detail::expression::result_type>, bool>::type @@ -282,13 +334,15 @@ inline typename enable_if::result_type t(a); typename detail::expression::result_type t2(b); - return eval_gt(t.backend(), t2.backend()); + if(detail::is_unordered_comparison(t, t2)) return false; + return t > t2; } template inline bool operator <= (const number& a, const number& b) { using default_ops::eval_gt; + if(detail::is_unordered_comparison(a, b)) return false; return !eval_gt(a.backend(), b.backend()); } template @@ -296,6 +350,7 @@ inline typename enable_if_c& a, const Arithmetic& b) { using default_ops::eval_gt; + if(detail::is_unordered_comparison(a, b)) return false; return !eval_gt(a.backend(), number::canonical_value(b)); } template @@ -303,6 +358,7 @@ inline typename enable_if_c& b) { using default_ops::eval_lt; + if(detail::is_unordered_comparison(a, b)) return false; return !eval_lt(b.backend(), number::canonical_value(a)); } template @@ -311,7 +367,10 @@ inline typename enable_if_c::result_type result_type; using default_ops::eval_lt; + if(detail::is_unordered_value(a) || detail::is_unordered_value(b)) + return false; result_type t(b); + if(detail::is_unordered_comparison(a, t)) return false; return !eval_lt(t.backend(), result_type::canonical_value(a)); } template @@ -321,6 +380,7 @@ inline typename enable_if_c::result_type result_type; using default_ops::eval_gt; result_type t(a); + if(detail::is_unordered_comparison(t, b)) return false; return !eval_gt(t.backend(), result_type::canonical_value(b)); } template @@ -330,6 +390,7 @@ inline typename enable_if::result_type t(a); typename detail::expression::result_type t2(b); + if(detail::is_unordered_comparison(t, t2)) return false; return !eval_gt(t.backend(), t2.backend()); } @@ -337,6 +398,7 @@ template = (const number& a, const number& b) { using default_ops::eval_lt; + if(detail::is_unordered_comparison(a, b)) return false; return !eval_lt(a.backend(), b.backend()); } template @@ -344,6 +406,7 @@ inline typename enable_if_c= (const number& a, const Arithmetic& b) { using default_ops::eval_lt; + if(detail::is_unordered_comparison(a, b)) return false; return !eval_lt(a.backend(), number::canonical_value(b)); } template @@ -351,6 +414,7 @@ inline typename enable_if_c= (const Arithmetic& a, const number& b) { using default_ops::eval_gt; + if(detail::is_unordered_comparison(a, b)) return false; return !eval_gt(b.backend(), number::canonical_value(a)); } template @@ -360,6 +424,7 @@ inline typename enable_if_c::result_type result_type; using default_ops::eval_gt; result_type t(b); + if(detail::is_unordered_comparison(a, t)) return false; return !eval_gt(t.backend(), result_type::canonical_value(a)); } template @@ -369,6 +434,7 @@ inline typename enable_if_c::result_type result_type; using default_ops::eval_lt; result_type t(a); + if(detail::is_unordered_comparison(t, b)) return false; return !eval_lt(t.backend(), result_type::canonical_value(b)); } template @@ -378,6 +444,7 @@ inline typename enable_if::result_type t(a); typename detail::expression::result_type t2(b); + if(detail::is_unordered_comparison(t, t2)) return false; return !eval_lt(t.backend(), t2.backend()); } diff --git a/test/test_arithmetic.hpp b/test/test_arithmetic.hpp index d787f938..b5488954 100644 --- a/test/test_arithmetic.hpp +++ b/test/test_arithmetic.hpp @@ -757,6 +757,44 @@ void test_float_funcs(const boost::mpl::true_&) BOOST_CHECK_CLOSE_FRACTION(b, Real(atan2(Real(4), Real(2))), tol); } +template +void compare_NaNs(const T& a, const U& b) +{ + BOOST_CHECK_EQUAL(a == b, false); + BOOST_CHECK_EQUAL(a != b, true); + BOOST_CHECK_EQUAL(a <= b, false); + BOOST_CHECK_EQUAL(a >= b, false); + BOOST_CHECK_EQUAL(a > b, false); + BOOST_CHECK_EQUAL(a < b, false); + // + // Again where LHS may be an expression template: + // + BOOST_CHECK_EQUAL(1 * a == b, false); + BOOST_CHECK_EQUAL(1 * a != b, true); + BOOST_CHECK_EQUAL(1 * a <= b, false); + BOOST_CHECK_EQUAL(1 * a >= b, false); + BOOST_CHECK_EQUAL(1 * a > b, false); + BOOST_CHECK_EQUAL(1 * a < b, false); + // + // Again where RHS may be an expression template: + // + BOOST_CHECK_EQUAL(a == b * 1, false); + BOOST_CHECK_EQUAL(a != b * 1, true); + BOOST_CHECK_EQUAL(a <= b * 1, false); + BOOST_CHECK_EQUAL(a >= b * 1, false); + BOOST_CHECK_EQUAL(a > b * 1, false); + BOOST_CHECK_EQUAL(a < b * 1, false); + // + // Again where LHS and RHS may be an expression templates: + // + BOOST_CHECK_EQUAL(1 * a == b * 1, false); + BOOST_CHECK_EQUAL(1 * a != b * 1, true); + BOOST_CHECK_EQUAL(1 * a <= b * 1, false); + BOOST_CHECK_EQUAL(1 * a >= b * 1, false); + BOOST_CHECK_EQUAL(1 * a > b * 1, false); + BOOST_CHECK_EQUAL(1 * a < b * 1, false); +} + template void test_float_ops(const T&){} @@ -861,6 +899,33 @@ void test_float_ops(const boost::mpl::int_::has_quiet_NaN) + { + r = v = std::numeric_limits::quiet_NaN(); + compare_NaNs(r, v); + v = 0; + compare_NaNs(r, v); + r.swap(v); + compare_NaNs(r, v); + // + // Conmpare NaN to int: + // + compare_NaNs(v, 0); + compare_NaNs(0, v); + // + // Compare to floats: + // + compare_NaNs(v, 0.5); + compare_NaNs(0.5, v); + if(std::numeric_limits::has_quiet_NaN) + { + compare_NaNs(r, std::numeric_limits::quiet_NaN()); + compare_NaNs(std::numeric_limits::quiet_NaN(), r); + } + } test_float_funcs(boost::mpl::bool_::is_specialized>()); } From 9aceb0bb9f134916b51a31d24b5ca4b181a1ceb5 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Tue, 7 Apr 2015 17:57:57 +0100 Subject: [PATCH 05/33] Fix digit count for 128-bit quad-float types. As per discussion here: http://www.exploringbinary.com/7-bits-are-not-enough-for-2-digit-accuracy/comment-page-1/#comment-9358 --- include/boost/multiprecision/float128.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/multiprecision/float128.hpp b/include/boost/multiprecision/float128.hpp index d736f8ae..cda8e824 100644 --- a/include/boost/multiprecision/float128.hpp +++ b/include/boost/multiprecision/float128.hpp @@ -534,7 +534,7 @@ public: static number_type (max)() BOOST_NOEXCEPT { return 1.18973149535723176508575932662800702e4932Q; } static number_type lowest() BOOST_NOEXCEPT { return -(max)(); } BOOST_STATIC_CONSTEXPR int digits = 113; - BOOST_STATIC_CONSTEXPR int digits10 = 34; + BOOST_STATIC_CONSTEXPR int digits10 = 33; BOOST_STATIC_CONSTEXPR int max_digits10 = 36; BOOST_STATIC_CONSTEXPR bool is_signed = true; BOOST_STATIC_CONSTEXPR bool is_integer = false; From 9d136406c8c2bd9009c5d8b9f83e05c6ff6ed856 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Tue, 7 Apr 2015 18:46:23 +0100 Subject: [PATCH 06/33] Fix digits10 calculation so it gets it correct in the 113-bit precision case. --- include/boost/multiprecision/cpp_bin_float.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/multiprecision/cpp_bin_float.hpp b/include/boost/multiprecision/cpp_bin_float.hpp index 1b11c782..f14d765e 100644 --- a/include/boost/multiprecision/cpp_bin_float.hpp +++ b/include/boost/multiprecision/cpp_bin_float.hpp @@ -1462,9 +1462,9 @@ public: return -(max)(); } BOOST_STATIC_CONSTEXPR int digits = boost::multiprecision::cpp_bin_float::bit_count; - BOOST_STATIC_CONSTEXPR int digits10 = digits * 301 / 1000; + BOOST_STATIC_CONSTEXPR int digits10 = (digits - 1) * 301 / 1000; // Is this really correct??? - BOOST_STATIC_CONSTEXPR int max_digits10 = digits10 + 2; + BOOST_STATIC_CONSTEXPR int max_digits10 = (digits * 301 / 1000) + 2; BOOST_STATIC_CONSTEXPR bool is_signed = true; BOOST_STATIC_CONSTEXPR bool is_integer = false; BOOST_STATIC_CONSTEXPR bool is_exact = false; From 689e66d28d4264e8e37b2c889f6eb10976c0bef9 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Fri, 17 Apr 2015 08:30:45 +0100 Subject: [PATCH 07/33] Fix self assignment bug in mpfr_float Fixes: https://svn.boost.org/trac/boost/ticket/11193 --- include/boost/multiprecision/mpfr.hpp | 13 ++++++++----- test/test_arithmetic.hpp | 6 ++++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/include/boost/multiprecision/mpfr.hpp b/include/boost/multiprecision/mpfr.hpp index 02e13a02..ac7699c0 100644 --- a/include/boost/multiprecision/mpfr.hpp +++ b/include/boost/multiprecision/mpfr.hpp @@ -831,11 +831,14 @@ struct mpfr_float_backend<0, allocate_dynamic> : public detail::mpfr_float_imp<0 mpfr_float_backend& operator=(const mpfr_float_backend& o) { - if(this->m_data[0]._mpfr_d == 0) - mpfr_init2(this->m_data, mpfr_get_prec(o.data())); - else - mpfr_set_prec(this->m_data, mpfr_get_prec(o.data())); - mpfr_set(this->m_data, o.data(), GMP_RNDN); + if(this != &o) + { + if(this->m_data[0]._mpfr_d == 0) + mpfr_init2(this->m_data, mpfr_get_prec(o.data())); + else + 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_CXX11_RVALUE_REFERENCES diff --git a/test/test_arithmetic.hpp b/test/test_arithmetic.hpp index b5488954..95d4fbc8 100644 --- a/test/test_arithmetic.hpp +++ b/test/test_arithmetic.hpp @@ -1905,5 +1905,11 @@ void test() // Destructor of "a" checks destruction of moved-from-object... Real m3(static_cast(a)); #endif + // + // Bug cases, self assignment first: + // + a = 20; + a = a; + BOOST_CHECK_EQUAL(a, 20); } From 524414edba04f5980dff6d3d87d1d46faab712dd Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Sat, 25 Apr 2015 11:31:17 +0100 Subject: [PATCH 08/33] Add workaround for GCC-5.1.0 numeric_limits. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65883 --- include/boost/multiprecision/cpp_int/multiply.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/boost/multiprecision/cpp_int/multiply.hpp b/include/boost/multiprecision/cpp_int/multiply.hpp index fd569faa..dbf256e9 100644 --- a/include/boost/multiprecision/cpp_int/multiply.hpp +++ b/include/boost/multiprecision/cpp_int/multiply.hpp @@ -130,10 +130,12 @@ inline typename enable_if_c::is_specialized || ((std::numeric_limits::max)() - carry > static_cast(cpp_int_backend::max_limb_value) * static_cast(cpp_int_backend::max_limb_value))); +#endif carry += static_cast(pa[i]) * static_cast(pb[j]); BOOST_ASSERT(!std::numeric_limits::is_specialized || ((std::numeric_limits::max)() - carry >= pr[i+j])); carry += pr[i + j]; From c71a3649aeab817f4fea52ffedca96e1f6bb25f6 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Sat, 25 Apr 2015 11:33:41 +0100 Subject: [PATCH 09/33] Ooops, fix previous commit. --- include/boost/multiprecision/cpp_int/multiply.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/multiprecision/cpp_int/multiply.hpp b/include/boost/multiprecision/cpp_int/multiply.hpp index dbf256e9..dbd8e29a 100644 --- a/include/boost/multiprecision/cpp_int/multiply.hpp +++ b/include/boost/multiprecision/cpp_int/multiply.hpp @@ -130,7 +130,7 @@ inline typename enable_if_c::is_specialized || ((std::numeric_limits::max)() - carry > From 0adcc3c0559ab1964fe3125c614edbb0aa83cbce Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Thu, 7 May 2015 16:25:27 +0100 Subject: [PATCH 10/33] Disable testing with external libraries when clang memory-santizer is in effect --- config/Jamfile.v2 | 18 +++++++++--------- config/has_gmp.cpp | 3 ++- config/has_mpfi.cpp | 6 ++++++ config/has_mpfr.cpp | 6 ++++++ config/has_tommath.cpp | 4 +++- 5 files changed, 26 insertions(+), 11 deletions(-) diff --git a/config/Jamfile.v2 b/config/Jamfile.v2 index 563671f2..38eaa3d7 100644 --- a/config/Jamfile.v2 +++ b/config/Jamfile.v2 @@ -40,15 +40,16 @@ lib gmp ; lib mpfr ; lib mpfi ; lib quadmath ; +lib tommath ; -exe has_gmp : has_gmp.cpp gmp : - $(gmp_path) $(gmp_path)/mpfr $(gmp_path)/gmpfrxx ; -exe has_mpfr : has_mpfr.cpp mpfr gmp : - $(mpfr_path) $(gmp_path)/mpfr $(gmp_path)/gmpfrxx $(gmp_path) ; -exe has_mpfi : has_mpfi.cpp mpfi mpfr gmp : - $(mpfr_path) $(gmp_path)/mpfr $(gmp_path)/gmpfrxx $(gmp_path) ; -obj has_tommath : has_tommath.cpp : - $(tommath_path) ; +run has_gmp.cpp gmp : : : + $(gmp_path) $(gmp_path)/mpfr $(gmp_path)/gmpfrxx : has_gmp ; +run has_mpfr.cpp mpfr gmp : : : + $(mpfr_path) $(gmp_path)/mpfr $(gmp_path)/gmpfrxx $(gmp_path) : has_mpfr ; +run has_mpfi.cpp mpfi mpfr gmp : : : + $(mpfr_path) $(gmp_path)/mpfr $(gmp_path)/gmpfrxx $(gmp_path) : has_mpfi ; +run has_tommath.cpp tommath : : : + $(tommath_path) : has_tommath ; run has_float128.cpp quadmath : : : : has_float128 ; exe has_intel_quad : has_intel_quad.cpp : -Qoption,cpp,--extended_float_type ; @@ -61,4 +62,3 @@ explicit has_intel_quad ; - diff --git a/config/has_gmp.cpp b/config/has_gmp.cpp index 33279830..ae93d38e 100644 --- a/config/has_gmp.cpp +++ b/config/has_gmp.cpp @@ -26,7 +26,8 @@ int main() mpz_t integ; mpz_init (integ); - mpz_clear (integ); + if(integ[0]._mp_d) + mpz_clear (integ); return 0; } diff --git a/config/has_mpfi.cpp b/config/has_mpfi.cpp index 0bb35645..fce42859 100644 --- a/config/has_mpfi.cpp +++ b/config/has_mpfi.cpp @@ -51,6 +51,12 @@ int main() mpfr_buildopt_tls_p(); + mpfi_t t; + mpfi_init2(t, 128); + if(t[0].left._mpfr_d) + mpfi_clear(t); + + return 0; } diff --git a/config/has_mpfr.cpp b/config/has_mpfr.cpp index add5853c..0603bc4c 100644 --- a/config/has_mpfr.cpp +++ b/config/has_mpfr.cpp @@ -28,6 +28,7 @@ #error "Incompatible GMP version" #endif + int main() { void *(*alloc_func_ptr) (size_t); @@ -38,6 +39,11 @@ int main() mpfr_buildopt_tls_p(); + mpfr_t t; + mpfr_init2(t, 128); + if(t[0]._mpfr_d) + mpfr_clear(t); + return 0; } diff --git a/config/has_tommath.cpp b/config/has_tommath.cpp index 19f1d801..7eb21833 100644 --- a/config/has_tommath.cpp +++ b/config/has_tommath.cpp @@ -5,11 +5,13 @@ #include + int main() { mp_int v; mp_init(&v); - mp_clear(&v); + if(v.dp) + mp_clear(&v); return 0; } From 6a2587159f08b2929f3935a719a06a6bbd026180 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Sat, 16 May 2015 11:16:11 +0100 Subject: [PATCH 11/33] Remove all uses of std::abs. Sadly it's still not implemented for all integer types on some platforms, see: https://svn.boost.org/trac/boost/ticket/11311 Plus "unsigned_abs" does what we actually want in most cases - ie does the right thing when the value is std::numeric_limits::min() without invoking undefined behavior. --- .../boost/multiprecision/cpp_int/divide.hpp | 2 +- .../detail/generic_interconvert.hpp | 2 +- include/boost/multiprecision/gmp.hpp | 26 +++++++++---------- include/boost/multiprecision/mpfi.hpp | 2 +- include/boost/multiprecision/tommath.hpp | 4 +-- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/include/boost/multiprecision/cpp_int/divide.hpp b/include/boost/multiprecision/cpp_int/divide.hpp index b5c9b5e2..c94bc714 100644 --- a/include/boost/multiprecision/cpp_int/divide.hpp +++ b/include/boost/multiprecision/cpp_int/divide.hpp @@ -540,7 +540,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c* >(0), a, static_cast(std::abs(b)), result); + divide_unsigned_helper(static_cast* >(0), a, static_cast(boost::multiprecision::detail::unsigned_abs(b)), result); result.sign(s); } diff --git a/include/boost/multiprecision/detail/generic_interconvert.hpp b/include/boost/multiprecision/detail/generic_interconvert.hpp index b261d81e..69f939fe 100644 --- a/include/boost/multiprecision/detail/generic_interconvert.hpp +++ b/include/boost/multiprecision/detail/generic_interconvert.hpp @@ -314,7 +314,7 @@ typename enable_if_c::value || is_floating_point::value>::type if(shift > 0) num <<= shift; else if(shift < 0) - denom <<= std::abs(shift); + denom <<= boost::multiprecision::detail::unsigned_abs(shift); Integer q, r; divide_qr(num, denom, q, r); int q_bits = msb(q); diff --git a/include/boost/multiprecision/gmp.hpp b/include/boost/multiprecision/gmp.hpp index 097c298e..1442d8a7 100644 --- a/include/boost/multiprecision/gmp.hpp +++ b/include/boost/multiprecision/gmp.hpp @@ -643,7 +643,7 @@ inline void eval_add(gmp_float& result, long i) if(i > 0) mpf_add_ui(result.data(), result.data(), i); else - mpf_sub_ui(result.data(), result.data(), std::abs(i)); + mpf_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i)); } template inline void eval_subtract(gmp_float& result, long i) @@ -651,12 +651,12 @@ inline void eval_subtract(gmp_float& result, long i) if(i > 0) mpf_sub_ui(result.data(), result.data(), i); else - mpf_add_ui(result.data(), result.data(), std::abs(i)); + mpf_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i)); } template inline void eval_multiply(gmp_float& result, long i) { - mpf_mul_ui(result.data(), result.data(), std::abs(i)); + mpf_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i)); if(i < 0) mpf_neg(result.data(), result.data()); } @@ -665,7 +665,7 @@ inline void eval_divide(gmp_float& result, long i) { if(i == 0) BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero.")); - mpf_div_ui(result.data(), result.data(), std::abs(i)); + mpf_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i)); if(i < 0) mpf_neg(result.data(), result.data()); } @@ -1410,19 +1410,19 @@ inline void eval_subtract(gmp_int& t, long i) } inline void eval_multiply(gmp_int& t, long i) { - mpz_mul_ui(t.data(), t.data(), std::abs(i)); + mpz_mul_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i)); if(i < 0) mpz_neg(t.data(), t.data()); } inline void eval_modulus(gmp_int& t, long i) { - mpz_tdiv_r_ui(t.data(), t.data(), std::abs(i)); + mpz_tdiv_r_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i)); } inline void eval_divide(gmp_int& t, long i) { if(i == 0) BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero.")); - mpz_tdiv_q_ui(t.data(), t.data(), std::abs(i)); + mpz_tdiv_q_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i)); if(i < 0) mpz_neg(t.data(), t.data()); } @@ -1522,19 +1522,19 @@ inline void eval_subtract(gmp_int& t, const gmp_int& p, long i) } inline void eval_multiply(gmp_int& t, const gmp_int& p, long i) { - mpz_mul_ui(t.data(), p.data(), std::abs(i)); + mpz_mul_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i)); if(i < 0) mpz_neg(t.data(), t.data()); } inline void eval_modulus(gmp_int& t, const gmp_int& p, long i) { - mpz_tdiv_r_ui(t.data(), p.data(), std::abs(i)); + mpz_tdiv_r_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i)); } inline void eval_divide(gmp_int& t, const gmp_int& p, long i) { if(i == 0) BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero.")); - mpz_tdiv_q_ui(t.data(), p.data(), std::abs(i)); + mpz_tdiv_q_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i)); if(i < 0) mpz_neg(t.data(), t.data()); } @@ -1613,12 +1613,12 @@ inline typename enable_if_c<(is_unsigned::value && (sizeof(I) <= sizeof(unsig template inline typename enable_if_c<(is_signed::value && (sizeof(I) <= sizeof(long)))>::type eval_gcd(gmp_int& result, const gmp_int& a, const I b) { - mpz_gcd_ui(result.data(), a.data(), std::abs(b)); + mpz_gcd_ui(result.data(), a.data(), boost::multiprecision::detail::unsigned_abs(b)); } template inline typename enable_if_c::value && ((sizeof(I) <= sizeof(long)))>::type eval_lcm(gmp_int& result, const gmp_int& a, const I b) { - mpz_lcm_ui(result.data(), a.data(), std::abs(b)); + mpz_lcm_ui(result.data(), a.data(), boost::multiprecision::detail::unsigned_abs(b)); } inline void eval_integer_sqrt(gmp_int& s, gmp_int& r, const gmp_int& x) @@ -1696,7 +1696,7 @@ template inline typename enable_if, Integer>::type eval_integer_modulus(const gmp_int& x, Integer val) { typedef typename make_unsigned::type unsigned_type; - return eval_integer_modulus(x, static_cast(std::abs(val))); + return eval_integer_modulus(x, boost::multiprecision::detail::unsigned_abs(val)); } inline void eval_powm(gmp_int& result, const gmp_int& base, const gmp_int& p, const gmp_int& m) { diff --git a/include/boost/multiprecision/mpfi.hpp b/include/boost/multiprecision/mpfi.hpp index 7dc2b9d7..8d13981c 100644 --- a/include/boost/multiprecision/mpfi.hpp +++ b/include/boost/multiprecision/mpfi.hpp @@ -128,7 +128,7 @@ struct mpfi_float_imp 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)))); + mpfi_init2(t, (std::max)(static_cast(std::numeric_limits::digits), static_cast(multiprecision::detail::digits10_2_2(digits10)))); mpfi_set_ui(m_data, 0); while(i) { diff --git a/include/boost/multiprecision/tommath.hpp b/include/boost/multiprecision/tommath.hpp index 90b1b788..65fb667a 100644 --- a/include/boost/multiprecision/tommath.hpp +++ b/include/boost/multiprecision/tommath.hpp @@ -118,7 +118,7 @@ struct tommath_int if(m_data.dp == 0) detail::check_tommath_result(mp_init(&m_data)); bool neg = i < 0; - *this = static_cast(std::abs(i)); + *this = boost::multiprecision::detail::unsigned_abs(i); if(neg) detail::check_tommath_result(mp_neg(&m_data, &m_data)); return *this; @@ -641,7 +641,7 @@ template inline typename enable_if, Integer>::type eval_integer_modulus(const tommath_int& x, Integer val) { typedef typename make_unsigned::type unsigned_type; - return eval_integer_modulus(x, static_cast(std::abs(val))); + return eval_integer_modulus(x, boost::multiprecision::detail::unsigned_abs(val)); } } // namespace backends From 3b41c0af07e85382830093ee18f04c0861660360 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Mon, 18 May 2015 11:59:25 +0100 Subject: [PATCH 12/33] Stop using run in configure rules: It breaks testing for some strange reason. --- config/Jamfile.v2 | 24 +++++++++++++++++++----- test/Jamfile.v2 | 6 +++--- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/config/Jamfile.v2 b/config/Jamfile.v2 index 38eaa3d7..b202727a 100644 --- a/config/Jamfile.v2 +++ b/config/Jamfile.v2 @@ -42,15 +42,29 @@ lib mpfi ; lib quadmath ; lib tommath ; -run has_gmp.cpp gmp : : : +actions mp_simple_run_action +{ + $(>) > $(<) +} + +rule mp-run-simple ( sources + : args * : input-files * : requirements * : target-name ) +{ + exe $(target-name)_exe : $(sources) : $(requirements) ; + explicit $(target-name)_exe ; + make $(target-name).output : $(target-name)_exe : @mp_simple_run_action ; + explicit $(target-name).output ; + alias $(target-name) : $(target-name).output ; +} + +mp-run-simple has_gmp.cpp gmp : : : $(gmp_path) $(gmp_path)/mpfr $(gmp_path)/gmpfrxx : has_gmp ; -run has_mpfr.cpp mpfr gmp : : : +mp-run-simple has_mpfr.cpp mpfr gmp : : : $(mpfr_path) $(gmp_path)/mpfr $(gmp_path)/gmpfrxx $(gmp_path) : has_mpfr ; -run has_mpfi.cpp mpfi mpfr gmp : : : +mp-run-simple has_mpfi.cpp mpfi mpfr gmp : : : $(mpfr_path) $(gmp_path)/mpfr $(gmp_path)/gmpfrxx $(gmp_path) : has_mpfi ; -run has_tommath.cpp tommath : : : +mp-run-simple has_tommath.cpp tommath : : : $(tommath_path) : has_tommath ; -run has_float128.cpp quadmath : : : : has_float128 ; +mp-run-simple has_float128.cpp quadmath : : : : has_float128 ; exe has_intel_quad : has_intel_quad.cpp : -Qoption,cpp,--extended_float_type ; explicit has_gmp ; diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 0ec5ea08..7cbb10b1 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -156,7 +156,7 @@ run test_numeric_limits.cpp gmp [ check-target-builds ../config//has_gmp : : no ] : test_numeric_limits_mpq ; -run test_numeric_limits.cpp mpfr +run test_numeric_limits.cpp mpfr gmp : # command line : # input files : # requirements @@ -164,7 +164,7 @@ run test_numeric_limits.cpp mpfr [ check-target-builds ../config//has_mpfr : : no ] : test_numeric_limits_mpfr ; -run test_numeric_limits.cpp mpfr +run test_numeric_limits.cpp mpfr gmp : # command line : # input files : # requirements @@ -296,7 +296,7 @@ run test_constants.cpp gmp [ check-target-builds ../config//has_gmp : : no ] : test_constants_mpf50 ; -run test_constants.cpp mpfr +run test_constants.cpp mpfr gmp : # command line : # input files : # requirements From f89bac311baf8a7fa84509095b826e4a4704deaf Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Sat, 30 May 2015 11:39:39 +0100 Subject: [PATCH 13/33] Fix right shifting of negative values in cpp_int. To give the same values as 2's complement representations, though not the same bit-pattern. Updated tests. Fixed assignment from float to not rely on shifting negative values. --- include/boost/multiprecision/cpp_int.hpp | 7 ++++ .../boost/multiprecision/cpp_int/bitwise.hpp | 36 +++++++++++++++++-- test/test_cpp_int.cpp | 8 +++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/include/boost/multiprecision/cpp_int.hpp b/include/boost/multiprecision/cpp_int.hpp index 26fee765..08d544cb 100644 --- a/include/boost/multiprecision/cpp_int.hpp +++ b/include/boost/multiprecision/cpp_int.hpp @@ -1224,6 +1224,13 @@ private: using std::ldexp; using std::floor; + if(a < 0) + { + do_assign_arithmetic(-a, mpl::false_()); + this->sign(true); + return; + } + if (a == 0) { *this = static_cast(0u); } diff --git a/include/boost/multiprecision/cpp_int/bitwise.hpp b/include/boost/multiprecision/cpp_int/bitwise.hpp index 98277d69..e18f3569 100644 --- a/include/boost/multiprecision/cpp_int/bitwise.hpp +++ b/include/boost/multiprecision/cpp_int/bitwise.hpp @@ -24,6 +24,22 @@ void is_valid_bitwise_op( cpp_int_backend&, const cpp_int_backend& , const mpl::int_&){} +template +void is_valid_bitwise_op( + const cpp_int_backend& result, const mpl::int_&) +{ + if(result.sign()) + BOOST_THROW_EXCEPTION(std::range_error("Bitwise operations on negative values results in undefined behavior.")); +} + +template +void is_valid_bitwise_op( + const cpp_int_backend&, const mpl::int_&){} + +template +void is_valid_bitwise_op( + cpp_int_backend&, const mpl::int_&){} + template void bitwise_op( CppInt1& result, @@ -285,6 +301,7 @@ inline typename enable_if_c& result, double_limb_type s) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { + is_valid_bitwise_op(result, typename cpp_int_backend::checked_type()); if(!s) return; @@ -361,16 +378,24 @@ inline typename enable_if_c& result, double_limb_type s) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { + is_valid_bitwise_op(result, typename cpp_int_backend::checked_type()); if(!s) return; + bool is_neg = result.sign(); + if(is_neg) + eval_increment(result); + limb_type offset = static_cast(s / cpp_int_backend::limb_bits); limb_type shift = static_cast(s % cpp_int_backend::limb_bits); unsigned ors = result.size(); unsigned rs = ors; if(offset >= rs) { - result = limb_type(0); + if(is_neg) + result = signed_limb_type(-1); + else + result = limb_type(0); return; } rs -= offset; @@ -379,7 +404,10 @@ inline typename enable_if_c > >::type eval_left_shift(cpp_int_backend& result, T s) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { + is_valid_bitwise_op(result, typename cpp_int_backend::checked_type()); *result.limbs() = detail::checked_left_shift(*result.limbs(), s, typename cpp_int_backend::checked_type()); result.normalize(); } @@ -417,6 +448,7 @@ BOOST_MP_FORCEINLINE typename enable_if& result, T s) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { // Nothing to check here... just make sure we don't invoke undefined behavior: + is_valid_bitwise_op(result, typename cpp_int_backend::checked_type()); *result.limbs() = (static_cast(s) >= sizeof(*result.limbs()) * CHAR_BIT) ? 0 : *result.limbs() >> s; } diff --git a/test/test_cpp_int.cpp b/test/test_cpp_int.cpp index 70c5f7b4..8172ec74 100644 --- a/test/test_cpp_int.cpp +++ b/test/test_cpp_int.cpp @@ -172,14 +172,22 @@ struct tester if(!std::numeric_limits::is_bounded) { BOOST_CHECK_EQUAL(mpz_int(a << i).str(), test_type(a1 << i).str()); + BOOST_CHECK_EQUAL(mpz_int(-a << i).str(), test_type(-a1 << i).str()); } else if(!is_checked_cpp_int::value) { test_type t1(mpz_int(a << i).str()); test_type t2 = a1 << i; BOOST_CHECK_EQUAL(t1, t2); + t1 = test_type(mpz_int(-a << i).str()); + t2 = -a1 << i; + BOOST_CHECK_EQUAL(t1, t2); } BOOST_CHECK_EQUAL(mpz_int(a >> i).str(), test_type(a1 >> i).str()); + if(!is_checked_cpp_int::value) + { + BOOST_CHECK_EQUAL(mpz_int(-a >> i).str(), test_type(-a1 >> i).str()); + } } // gcd/lcm BOOST_CHECK_EQUAL(mpz_int(gcd(a, b)).str(), test_type(gcd(a1, b1)).str()); From 26a7d613f7ed0e7d1dbc91ac9e73baac3d7caf67 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Sun, 31 May 2015 09:17:43 +0100 Subject: [PATCH 14/33] Update history Conflicts: doc/multiprecision.qbk --- doc/multiprecision.qbk | 59 ++++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 13 deletions(-) diff --git a/doc/multiprecision.qbk b/doc/multiprecision.qbk index e878c106..58700f7b 100644 --- a/doc/multiprecision.qbk +++ b/doc/multiprecision.qbk @@ -1607,33 +1607,60 @@ backends converting constructor is also explicit. [section:random Generating Random Numbers] -Random numbers are generated in conjunction with Boost.Random. However, since Boost.Random is unaware -of [@http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic arbitrary precision] numbers, it's necessary to include the header: +Random numbers are generated in conjunction with Boost.Random. - #include - -In order to act as a bridge between the two libraries. - -Integers with /N/ random bits are generated using `independent_bits_engine`: +There is a single generator that supports generating random integers with large bit counts: +[@http://www.boost.org/doc/html/boost/random/independent_bits_engine.html `independent_bits_engine`]. +This type can be used with either ['unbounded] integer types, or with ['bounded] (ie fixed precision) unsigned integers: [random_eg1] -Alternatively we can generate integers in a given range using `uniform_int_distribution`, this will +Program output is: + +[random_eg1_out] + +In addition, the generator adaptors [@http://www.boost.org/doc/html/boost/random/discard_block_engine.html `discard_block`], +[@http://www.boost.org/doc/html/boost/random/xor_combine_engine.html `xor_combine_engine`] and +[@http://www.boost.org/doc/html/boost/random/discrete_distribution.html `discrete_distribution`] can be used +with multiprecision types. Note that if you seed an `independent_bits_engine`, then you are actually seeding +the underlying generator, and should therefore provide a sequence of unsigned 32-bit values as the seed. + +Alternatively we can generate integers in a given range using +[@http://www.boost.org/doc/html/boost/random/uniform_int_distribution.html `uniform_int_distribution`], this will invoke the underlying engine multiple times to build up the required number of bits in the result: [random_eg2] -Floating point values in \[0,1) are generated using `uniform_01`, the trick here is to ensure -that the underlying generator produces as many random bits as there are digits in the floating -point type. As above `independent_bits_engine` can be used for this purpose, note that we also have to -convert decimal digits (in the floating point type) to bits (in the random number generator): +[random_eg2_out] + +It is also possible to use [@http://www.boost.org/doc/html/boost/random/uniform_int_distribution.html `uniform_int_distribution`] +with a multiprecision generator such as [@http://www.boost.org/doc/html/boost/random/independent_bits_engine.html `independent_bits_engine`]. +Or to use [@http://www.boost.org/doc/html/boost/random/uniform_smallint.html `uniform_smallint`] or +[@http://www.boost.org/doc/html/boost/random/random_number_generator.html `random_number_generator`] with multiprecision types. + +Floating point values in \[0,1) are most easily generated using [@http://www.boost.org/doc/html/boost/random/generate_canonical.html `generate_canonical`], +note that `generate_canonical` will call the generator multiple times to produce the requested number of bits, for example we can use +it with a regular generator like so: [random_eg3] -Finally, we can modify the above example to produce numbers distributed according to some distribution: +[random_eg3_out] + +Note however, the distributions do not invoke the generator multiple times to fill up the mantissa of a multiprecision floating point type +with random bits. For these therefore, we should probably use a multiprecision generator (ie `independent_bits_engine`) in combination +with the distribution: [random_eg4] +[random_eg4_out] + +And finally, it is possible to use the floating point generators [@http://www.boost.org/doc/html/boost/random/lagged_fibonacci_01_engine.html `lagged_fibonacci_01_engine`] +and [@http://www.boost.org/doc/html/boost/random/subtract_with_idp144360752.html `subtract_with_carry_01_engine`] directly with multiprecision floating point types. +It's worth noting however, that there is a distinct lack of literature on generating high bit-count random numbers, and therefore a lack of "known good" parameters to +use with these generators in this situation. For this reason, these should probably be used for research purposes only: + +[random_eg5] + [endsect] [section:primetest Primality Testing] @@ -4944,6 +4971,12 @@ Windows Vista machine. [section:hist History] +[h4 Multiprecision-2.2.5 (Boost-1.59)] + +* Depricated boost/multiprecision/random.hpp as it's no longer needed, updated random examples to match. +* Fixed a bug in cpp_int's right shift operator when shifting negative values - semantics now gives the +same values as shifting 2's compliment integers, though not the same bit pattern. + [h4 Multiprecision-2.2.4 (Boost-1.58)] * Changed `frexp` to always be non-expression template generating, see: [@https://svn.boost.org/trac/boost/ticket/10993 10993]. From 6abc91b3df70a6356af85e918101b4e7f0e59a76 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Sun, 31 May 2015 09:18:23 +0100 Subject: [PATCH 15/33] Fix MSVC analyzer warnings. --- .../boost/multiprecision/cpp_bin_float.hpp | 20 ++++++++++++++++--- .../boost/multiprecision/cpp_bin_float/io.hpp | 10 +++++----- .../boost/multiprecision/cpp_dec_float.hpp | 9 +++++++++ include/boost/multiprecision/cpp_int.hpp | 18 ++++++++--------- .../multiprecision/cpp_int/serialize.hpp | 2 +- .../multiprecision/detail/functions/pow.hpp | 8 ++++++++ .../multiprecision/detail/functions/trig.hpp | 20 +++++++++++++------ .../detail/generic_interconvert.hpp | 2 +- .../multiprecision/detail/number_base.hpp | 12 ++++++++++- include/boost/multiprecision/number.hpp | 2 +- .../cpp_bin_float_include_test.cpp | 5 ++++- .../cpp_dec_float_include_test.cpp | 5 ++++- test/include_test/cpp_int_include_test.cpp | 13 +++++++----- test/include_test/gmp_include_test.cpp | 9 ++++++--- test/include_test/mpfr_include_test.cpp | 5 ++++- test/include_test/tommath_include_test.cpp | 5 ++++- 16 files changed, 106 insertions(+), 39 deletions(-) diff --git a/include/boost/multiprecision/cpp_bin_float.hpp b/include/boost/multiprecision/cpp_bin_float.hpp index f14d765e..ec37bd38 100644 --- a/include/boost/multiprecision/cpp_bin_float.hpp +++ b/include/boost/multiprecision/cpp_bin_float.hpp @@ -21,7 +21,7 @@ enum digit_base_type #ifdef BOOST_MSVC #pragma warning(push) -#pragma warning(disable:4522) // multiple assignment operators specified +#pragma warning(disable:4522 6326) // multiple assignment operators specified, comparison of two constants #endif namespace detail{ @@ -37,7 +37,7 @@ template ::value ? bit_count : 0, bit_count, is_void::value ? unsigned_magnitude : signed_magnitude, unchecked, Allocator> rep_type; typedef cpp_int_backend::value ? 2 * bit_count : 0, 2 * bit_count, is_void::value ? unsigned_magnitude : signed_magnitude, unchecked, Allocator> double_rep_type; @@ -773,6 +773,10 @@ inline typename enable_if_c::value>::type eval_multiply(cpp_bin_flo template inline void eval_divide(cpp_bin_float &res, const cpp_bin_float &u, const cpp_bin_float &v) { +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:6326) // comparison of two constants +#endif using default_ops::eval_subtract; using default_ops::eval_qr; using default_ops::eval_bit_test; @@ -882,7 +886,7 @@ inline void eval_divide(cpp_bin_float::bit_count - 1)); - static const unsigned lshift = cpp_bin_float::bit_count < limb_bits ? 2 : limb_bits; + static const unsigned lshift = (cpp_bin_float::bit_count < limb_bits) ? 2 : limb_bits; eval_left_shift(q, lshift); res.exponent() -= lshift; eval_left_shift(r, 1u); @@ -893,6 +897,9 @@ inline void eval_divide(cpp_bin_float(1u) << (lshift - 1)) + static_cast(1u); } copy_and_round(res, q); +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif } template @@ -904,6 +911,10 @@ inline void eval_divide(cpp_bin_float inline typename enable_if_c::value>::type eval_divide(cpp_bin_float &res, const cpp_bin_float &u, const U &v) { +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:6326) // comparison of two constants +#endif using default_ops::eval_subtract; using default_ops::eval_qr; using default_ops::eval_bit_test; @@ -1000,6 +1011,9 @@ inline typename enable_if_c::value>::type eval_divide(cpp_bin_flo q.limbs()[0] |= (static_cast(1u) << (lshift - 1)) + static_cast(1u); } copy_and_round(res, q); +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif } template diff --git a/include/boost/multiprecision/cpp_bin_float/io.hpp b/include/boost/multiprecision/cpp_bin_float/io.hpp index ae3ab38e..88d5ddd0 100644 --- a/include/boost/multiprecision/cpp_bin_float/io.hpp +++ b/include/boost/multiprecision/cpp_bin_float/io.hpp @@ -282,7 +282,7 @@ cpp_bin_float& cpp_bin_float #ifdef BOOST_MP_STRESS_IO boost::intmax_t max_bits = cpp_bin_float::bit_count + 32; #else - boost::intmax_t max_bits = cpp_bin_float::bit_count + (cpp_bin_float::bit_count % limb_bits ? limb_bits - cpp_bin_float::bit_count % limb_bits : 0) + limb_bits; + boost::intmax_t max_bits = cpp_bin_float::bit_count + ((cpp_bin_float::bit_count % limb_bits) ? (limb_bits - cpp_bin_float::bit_count % limb_bits) : 0) + limb_bits; #endif boost::int64_t error = 0; boost::intmax_t calc_exp = 0; @@ -384,9 +384,9 @@ cpp_bin_float& cpp_bin_float { // Too many bits in q and the bits in q indicate a tie, but we can break that using r, // note that the radius of error in r is error/2 * q: - int shift = gb - (int)cpp_bin_float::bit_count + 1; - q >>= shift; - final_exponent += static_cast(shift); + int lshift = gb - (int)cpp_bin_float::bit_count + 1; + q >>= lshift; + final_exponent += static_cast(lshift); BOOST_ASSERT((msb(q) >= cpp_bin_float::bit_count - 1)); if(error && (r < (error / 2) * q)) roundup = -1; @@ -525,7 +525,7 @@ std::string cpp_bin_float::s #ifdef BOOST_MP_STRESS_IO boost::intmax_t max_bits = cpp_bin_float::bit_count + 32; #else - boost::intmax_t max_bits = cpp_bin_float::bit_count + (cpp_bin_float::bit_count % limb_bits ? limb_bits - cpp_bin_float::bit_count % limb_bits : 0) + limb_bits; + boost::intmax_t max_bits = cpp_bin_float::bit_count + ((cpp_bin_float::bit_count % limb_bits) ? (limb_bits - cpp_bin_float::bit_count % limb_bits) : 0) + limb_bits; if(power10) max_bits += (msb(boost::multiprecision::detail::abs(power10)) / 8) * limb_bits; #endif diff --git a/include/boost/multiprecision/cpp_dec_float.hpp b/include/boost/multiprecision/cpp_dec_float.hpp index ba0800bb..0dd0a40e 100644 --- a/include/boost/multiprecision/cpp_dec_float.hpp +++ b/include/boost/multiprecision/cpp_dec_float.hpp @@ -34,6 +34,11 @@ // #include +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:6326) // comparison of two constants +#endif + namespace boost{ namespace multiprecision{ namespace backends{ @@ -3078,4 +3083,8 @@ struct precision< boost::multiprecision::number >::type > @@ -181,8 +181,8 @@ public: BOOST_STATIC_CONSTANT(limb_type, sign_bit_mask = 1u << (limb_bits - 1)); BOOST_STATIC_CONSTANT(unsigned, internal_limb_count = MinBits - ? MinBits / limb_bits + (MinBits % limb_bits ? 1 : 0) - : sizeof(limb_data) / sizeof(limb_type)); + ? (MinBits / limb_bits + ((MinBits % limb_bits) ? 1 : 0)) + : (sizeof(limb_data) / sizeof(limb_type))); BOOST_STATIC_CONSTANT(bool, variable = true); private: @@ -243,7 +243,7 @@ public: } void resize(unsigned new_size, unsigned min_size) { - static const unsigned max_limbs = MaxBits / (CHAR_BIT * sizeof(limb_type)) + (MaxBits % (CHAR_BIT * sizeof(limb_type)) ? 1 : 0); + static const unsigned max_limbs = MaxBits / (CHAR_BIT * sizeof(limb_type)) + ((MaxBits % (CHAR_BIT * sizeof(limb_type))) ? 1 : 0); // We never resize beyond MaxSize: if(new_size > max_limbs) new_size = max_limbs; @@ -402,9 +402,9 @@ public: BOOST_STATIC_CONSTANT(unsigned, limb_bits = sizeof(limb_type) * CHAR_BIT); BOOST_STATIC_CONSTANT(limb_type, max_limb_value = ~static_cast(0u)); BOOST_STATIC_CONSTANT(limb_type, sign_bit_mask = 1u << (limb_bits - 1)); - BOOST_STATIC_CONSTANT(unsigned, internal_limb_count = MinBits / limb_bits + (MinBits % limb_bits ? 1 : 0)); + BOOST_STATIC_CONSTANT(unsigned, internal_limb_count = MinBits / limb_bits + ((MinBits % limb_bits) ? 1 : 0)); BOOST_STATIC_CONSTANT(bool, variable = false); - BOOST_STATIC_CONSTANT(limb_type, upper_limb_mask = MinBits % limb_bits ? (limb_type(1) << (MinBits % limb_bits)) -1 : (~limb_type(0))); + BOOST_STATIC_CONSTANT(limb_type, upper_limb_mask = (MinBits % limb_bits) ? (limb_type(1) << (MinBits % limb_bits)) -1 : (~limb_type(0))); BOOST_STATIC_ASSERT_MSG(internal_limb_count >= 2, "A fixed precision integer type must have at least 2 limbs"); private: @@ -554,9 +554,9 @@ public: BOOST_STATIC_CONSTANT(unsigned, limb_bits = sizeof(limb_type) * CHAR_BIT); BOOST_STATIC_CONSTANT(limb_type, max_limb_value = ~static_cast(0u)); BOOST_STATIC_CONSTANT(limb_type, sign_bit_mask = 1u << (limb_bits - 1)); - BOOST_STATIC_CONSTANT(unsigned, internal_limb_count = MinBits / limb_bits + (MinBits % limb_bits ? 1 : 0)); + BOOST_STATIC_CONSTANT(unsigned, internal_limb_count = MinBits / limb_bits + ((MinBits % limb_bits) ? 1 : 0)); BOOST_STATIC_CONSTANT(bool, variable = false); - BOOST_STATIC_CONSTANT(limb_type, upper_limb_mask = MinBits % limb_bits ? (limb_type(1) << (MinBits % limb_bits)) -1 : (~limb_type(0))); + BOOST_STATIC_CONSTANT(limb_type, upper_limb_mask = (MinBits % limb_bits) ? (limb_type(1) << (MinBits % limb_bits)) -1 : (~limb_type(0))); BOOST_STATIC_ASSERT_MSG(internal_limb_count >= 2, "A fixed precision integer type must have at least 2 limbs"); private: @@ -1555,7 +1555,7 @@ private: limb_type shift = base == 8 ? 3 : 4; limb_type mask = static_cast((1u << shift) - 1); cpp_int_backend t(*this); - result.assign(Bits / shift + (Bits % shift ? 1 : 0), '0'); + result.assign(Bits / shift + ((Bits % shift) ? 1 : 0), '0'); std::string::difference_type pos = result.size() - 1; for(unsigned i = 0; i < Bits / shift; ++i) { diff --git a/include/boost/multiprecision/cpp_int/serialize.hpp b/include/boost/multiprecision/cpp_int/serialize.hpp index bdf4758a..042a9f89 100644 --- a/include/boost/multiprecision/cpp_int/serialize.hpp +++ b/include/boost/multiprecision/cpp_int/serialize.hpp @@ -49,7 +49,7 @@ void do_serialize(Archive& ar, Int& val, mpl::false_ const&, mpl::false_ const&, std::size_t limb_count; std::size_t byte_count; ar & byte_count; - limb_count = byte_count / sizeof(limb_type) + (byte_count % sizeof(limb_type) ? 1 : 0); + limb_count = byte_count / sizeof(limb_type) + ((byte_count % sizeof(limb_type)) ? 1 : 0); val.resize(limb_count, limb_count); limb_type* pl = val.limbs(); for(std::size_t i = 0; i < limb_count; ++i) diff --git a/include/boost/multiprecision/detail/functions/pow.hpp b/include/boost/multiprecision/detail/functions/pow.hpp index 5b54a1a9..44c0b38e 100644 --- a/include/boost/multiprecision/detail/functions/pow.hpp +++ b/include/boost/multiprecision/detail/functions/pow.hpp @@ -12,6 +12,11 @@ // This file has no include guards or namespaces - it's expanded inline inside default_ops.hpp // +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:6326) // comparison of two constants +#endif + namespace detail{ template @@ -692,3 +697,6 @@ inline void eval_tanh(T& result, const T& x) eval_divide(result, c); } +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif diff --git a/include/boost/multiprecision/detail/functions/trig.hpp b/include/boost/multiprecision/detail/functions/trig.hpp index baa42be3..5d4e2639 100644 --- a/include/boost/multiprecision/detail/functions/trig.hpp +++ b/include/boost/multiprecision/detail/functions/trig.hpp @@ -12,6 +12,11 @@ // This file has no include guards or namespaces - it's expanded inline inside default_ops.hpp // +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:6326) // comparison of two constants +#endif + template void hyp0F1(T& result, const T& b, const T& x) { @@ -494,12 +499,12 @@ void eval_asin(T& result, const T& x) // Newton-Raphson iteration while(current_digits < target_precision) { - T s, c; - eval_sin(s, result); - eval_cos(c, result); - eval_subtract(s, xx); - eval_divide(s, c); - eval_subtract(result, s); + T sine, cosine; + eval_sin(sine, result); + eval_cos(cosine, result); + eval_subtract(sine, xx); + eval_divide(sine, cosine); + eval_subtract(result, sine); current_digits *= 2; /* @@ -770,3 +775,6 @@ inline typename enable_if, void>::type eval_atan2(T& result, co eval_atan2(result, c, a); } +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif diff --git a/include/boost/multiprecision/detail/generic_interconvert.hpp b/include/boost/multiprecision/detail/generic_interconvert.hpp index 69f939fe..d1fa028d 100644 --- a/include/boost/multiprecision/detail/generic_interconvert.hpp +++ b/include/boost/multiprecision/detail/generic_interconvert.hpp @@ -10,7 +10,7 @@ #ifdef BOOST_MSVC #pragma warning(push) -#pragma warning(disable:4127) +#pragma warning(disable:4127 6326) #endif namespace boost{ namespace multiprecision{ namespace detail{ diff --git a/include/boost/multiprecision/detail/number_base.hpp b/include/boost/multiprecision/detail/number_base.hpp index d08b2a6e..4ff04edd 100644 --- a/include/boost/multiprecision/detail/number_base.hpp +++ b/include/boost/multiprecision/detail/number_base.hpp @@ -25,7 +25,13 @@ # define BOOST_MP_FORCEINLINE inline #endif -namespace boost{ namespace multiprecision{ +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable:6326) +#endif + +namespace boost{ + namespace multiprecision{ enum expression_template_option { @@ -814,6 +820,10 @@ namespace constants{ }} +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + #endif // BOOST_MATH_BIG_NUM_BASE_HPP diff --git a/include/boost/multiprecision/number.hpp b/include/boost/multiprecision/number.hpp index c977958e..321457c3 100644 --- a/include/boost/multiprecision/number.hpp +++ b/include/boost/multiprecision/number.hpp @@ -31,7 +31,7 @@ namespace boost{ namespace multiprecision{ // warning C4127: conditional expression is constant // warning C4714: function marked as __forceinline not inlined #pragma warning(push) -#pragma warning(disable:4127 4714) +#pragma warning(disable:4127 4714 6326) #endif template diff --git a/test/include_test/cpp_bin_float_include_test.cpp b/test/include_test/cpp_bin_float_include_test.cpp index b36c89e1..96862e87 100644 --- a/test/include_test/cpp_bin_float_include_test.cpp +++ b/test/include_test/cpp_bin_float_include_test.cpp @@ -7,6 +7,9 @@ using namespace boost::multiprecision; -cpp_bin_float<50> a; +int main() +{ + cpp_bin_float<50> a; +} diff --git a/test/include_test/cpp_dec_float_include_test.cpp b/test/include_test/cpp_dec_float_include_test.cpp index bdf09e83..1a721fcb 100644 --- a/test/include_test/cpp_dec_float_include_test.cpp +++ b/test/include_test/cpp_dec_float_include_test.cpp @@ -7,6 +7,9 @@ using namespace boost::multiprecision; -cpp_dec_float<50> a; +int main() +{ + cpp_dec_float<50> a; +} diff --git a/test/include_test/cpp_int_include_test.cpp b/test/include_test/cpp_int_include_test.cpp index e3742612..b7ad8285 100644 --- a/test/include_test/cpp_int_include_test.cpp +++ b/test/include_test/cpp_int_include_test.cpp @@ -7,10 +7,13 @@ using namespace boost::multiprecision; -number > a; -number, et_off> b; -number, et_off> c; -number, et_off> d; -number, et_off> e; +int main() +{ + number > a; + number, et_off> b; + number, et_off> c; + number, et_off> d; + number, et_off> e; +} diff --git a/test/include_test/gmp_include_test.cpp b/test/include_test/gmp_include_test.cpp index 4b07266f..7065ebd1 100644 --- a/test/include_test/gmp_include_test.cpp +++ b/test/include_test/gmp_include_test.cpp @@ -7,8 +7,11 @@ using namespace boost::multiprecision; -mpf_float a; -mpz_int b; -mpq_rational c; +int main() +{ + mpf_float a; + mpz_int b; + mpq_rational c; +} diff --git a/test/include_test/mpfr_include_test.cpp b/test/include_test/mpfr_include_test.cpp index f84cbb95..c49f24fc 100644 --- a/test/include_test/mpfr_include_test.cpp +++ b/test/include_test/mpfr_include_test.cpp @@ -7,6 +7,9 @@ using namespace boost::multiprecision; -mpfr_float a; +int main() +{ + mpfr_float a; +} diff --git a/test/include_test/tommath_include_test.cpp b/test/include_test/tommath_include_test.cpp index bc000fef..9f146dbf 100644 --- a/test/include_test/tommath_include_test.cpp +++ b/test/include_test/tommath_include_test.cpp @@ -7,6 +7,9 @@ using namespace boost::multiprecision; -tom_int a; +int main() +{ + tom_int a; +} From 90982e0191c239dca716fa8bc24c6e9406386cac Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Mon, 1 Jun 2015 18:11:11 +0100 Subject: [PATCH 16/33] Fix mixed mode comparison operators. See https://svn.boost.org/trac/boost/ticket/11328. And added tests for mixed mode comparisons and other operators. --- .../multiprecision/detail/number_compare.hpp | 58 +++--- .../multiprecision/traits/is_backend.hpp | 62 ++++++ test/Jamfile.v2 | 9 + test/test_mixed.hpp | 191 ++++++++++++++++++ test/test_mixed_cpp_bin_float.cpp | 33 +++ test/test_mixed_cpp_dec_float.cpp | 33 +++ test/test_mixed_mpf_float.cpp | 33 +++ test/test_mixed_mpfr_float.cpp | 33 +++ 8 files changed, 423 insertions(+), 29 deletions(-) create mode 100644 include/boost/multiprecision/traits/is_backend.hpp create mode 100644 test/test_mixed.hpp create mode 100644 test/test_mixed_cpp_bin_float.cpp create mode 100644 test/test_mixed_cpp_dec_float.cpp create mode 100644 test/test_mixed_mpf_float.cpp create mode 100644 test/test_mixed_mpfr_float.cpp diff --git a/include/boost/multiprecision/detail/number_compare.hpp b/include/boost/multiprecision/detail/number_compare.hpp index bddbf4a1..3ac34b79 100644 --- a/include/boost/multiprecision/detail/number_compare.hpp +++ b/include/boost/multiprecision/detail/number_compare.hpp @@ -6,6 +6,8 @@ #ifndef BOOST_MP_COMPARE_HPP #define BOOST_MP_COMPARE_HPP +#include + // // Comparison operators for number. // @@ -19,56 +21,54 @@ inline bool eval_eq(const B& a, const B& b) { return a.compare(b) == 0; } -// -// For the default version which compares to some arbitrary type convertible to -// our number type, we don't know what value the ExpressionTemplates parameter to -// class number should be. We generally prefer ExpressionTemplates to be enabled -// in case type A is itself an expression template, but we need to test both options -// with is_convertible in case A has an implicit conversion operator to number. -// This is the case with many uBlas types for example. -// -template -inline bool eval_eq(const B& a, const A& b) +template +inline typename enable_if_c::value, bool>::type eval_eq(const T& a, const U& b) { - typedef typename mpl::if_c< - is_convertible >::value, - number, - number >::type mp_type; - mp_type t(b); + typename boost::multiprecision::detail::number_from_backend::type t(b); return eval_eq(a, t.backend()); } +template +inline typename enable_if_c::value, bool>::type eval_eq(const T& a, const U& b) +{ + typename boost::multiprecision::detail::number_from_backend::type t(a); + return eval_eq(t.backend(), b); +} template inline bool eval_lt(const B& a, const B& b) { return a.compare(b) < 0; } -template -inline bool eval_lt(const B& a, const A& b) +template +inline typename enable_if_c::value, bool>::type eval_lt(const T& a, const U& b) { - typedef typename mpl::if_c< - is_convertible >::value, - number, - number >::type mp_type; - mp_type t(b); + typename boost::multiprecision::detail::number_from_backend::type t(b); return eval_lt(a, t.backend()); } +template +inline typename enable_if_c::value, bool>::type eval_lt(const T& a, const U& b) +{ + typename boost::multiprecision::detail::number_from_backend::type t(a); + return eval_lt(t.backend(), b); +} template inline bool eval_gt(const B& a, const B& b) { return a.compare(b) > 0; } -template -inline bool eval_gt(const B& a, const A& b) +template +inline typename enable_if_c::value, bool>::type eval_gt(const T& a, const U& b) { - typedef typename mpl::if_c< - is_convertible >::value, - number, - number >::type mp_type; - mp_type t(b); + typename boost::multiprecision::detail::number_from_backend::type t(b); return eval_gt(a, t.backend()); } +template +inline typename enable_if_c::value, bool>::type eval_gt(const T& a, const U& b) +{ + typename boost::multiprecision::detail::number_from_backend::type t(a); + return eval_gt(t.backend(), b); +} } // namespace default_ops diff --git a/include/boost/multiprecision/traits/is_backend.hpp b/include/boost/multiprecision/traits/is_backend.hpp new file mode 100644 index 00000000..bd9458c9 --- /dev/null +++ b/include/boost/multiprecision/traits/is_backend.hpp @@ -0,0 +1,62 @@ +/////////////////////////////////////////////////////////////////////////////// +// 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_0.txt) + +#ifndef BOOST_MP_IS_BACKEND_HPP +#define BOOST_MP_IS_BACKEND_HPP + +#include +#include +#include + +namespace boost{ namespace multiprecision{ namespace detail{ + + BOOST_MPL_HAS_XXX_TRAIT_DEF(signed_types); + BOOST_MPL_HAS_XXX_TRAIT_DEF(unsigned_types); + BOOST_MPL_HAS_XXX_TRAIT_DEF(float_types); + + template + struct is_backend + { + static const bool value = has_signed_types::value && has_unsigned_types::value && has_float_types::value; + }; + + template + struct other_backend + { + typedef typename boost::conditional< + boost::is_same, number >::value, + number, number >::type type; + }; + + template + struct number_from_backend + { + typedef typename boost::conditional < + boost::is_convertible >::value, + number, + typename other_backend::type > ::type type; + }; + + template + struct is_first_backend_imp{ static const bool value = false; }; + template + struct is_first_backend_imp{ static const bool value = is_convertible >::value || is_convertible >::value; }; + + template + struct is_first_backend : is_first_backend_imp::value, T, U> {}; + + template + struct is_second_backend_imp{ static const bool value = false; }; + template + struct is_second_backend_imp{ static const bool value = is_convertible >::value || is_convertible >::value; }; + + template + struct is_second_backend : is_second_backend_imp::value, T, U> {}; + +} +} +} + +#endif // BOOST_MP_IS_BACKEND_HPP diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 7cbb10b1..fd6ce7c4 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -670,6 +670,15 @@ run test_float128_serial.cpp ../../serialization/build//boost_serialization quad run test_cpp_bin_float_serial.cpp ../../serialization/build//boost_serialization : : : release TEST1 : test_bin_dec_float_serial_1 ; run test_cpp_bin_float_serial.cpp ../../serialization/build//boost_serialization : : : release TEST2 : test_bin_dec_float_serial_2 ; +# +# Mixed mode comparison tests, see: https://svn.boost.org/trac/boost/ticket/11328 +# +run test_checked_mixed_cpp_int.cpp ; +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 ] ; + if $(enable-specfun) { diff --git a/test/test_mixed.hpp b/test/test_mixed.hpp new file mode 100644 index 00000000..d6a497cd --- /dev/null +++ b/test/test_mixed.hpp @@ -0,0 +1,191 @@ +/////////////////////////////////////////////////////////////////////////////// +// 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_0.txt) + +#ifndef BOOST_MATH_TEST_MIXED_HPP +#define BOOST_MATH_TEST_MIXED_HPP + +#include "test.hpp" + +template +void test() +{ + Big big_val = 1; + big_val += std::numeric_limits::epsilon(); + Small small_val = 1; + + BOOST_CHECK_EQUAL(big_val == small_val, false); + BOOST_CHECK_EQUAL(big_val <= small_val, false); + BOOST_CHECK_EQUAL(big_val >= small_val, true); + BOOST_CHECK_EQUAL(big_val < small_val, false); + BOOST_CHECK_EQUAL(big_val > small_val, true); + BOOST_CHECK_EQUAL(big_val != small_val, true); + BOOST_CHECK_EQUAL(small_val == big_val, false); + BOOST_CHECK_EQUAL(small_val <= big_val, true); + BOOST_CHECK_EQUAL(small_val >= big_val, false); + BOOST_CHECK_EQUAL(small_val < big_val, true); + BOOST_CHECK_EQUAL(small_val > big_val, false); + BOOST_CHECK_EQUAL(small_val != big_val, true); + // Again with expression templates, on one the other, or both args: + BOOST_CHECK_EQUAL(big_val == small_val * 1, false); + BOOST_CHECK_EQUAL(big_val <= small_val * 1, false); + BOOST_CHECK_EQUAL(big_val >= small_val * 1, true); + BOOST_CHECK_EQUAL(big_val < small_val * 1, false); + BOOST_CHECK_EQUAL(big_val > small_val * 1, true); + BOOST_CHECK_EQUAL(big_val != small_val * 1, true); + BOOST_CHECK_EQUAL(small_val * 1 == big_val, false); + BOOST_CHECK_EQUAL(small_val * 1 <= big_val, true); + BOOST_CHECK_EQUAL(small_val * 1 >= big_val, false); + BOOST_CHECK_EQUAL(small_val * 1 < big_val, true); + BOOST_CHECK_EQUAL(small_val * 1 > big_val, false); + BOOST_CHECK_EQUAL(small_val * 1 != big_val, true); + BOOST_CHECK_EQUAL(big_val * 1 == small_val, false); + BOOST_CHECK_EQUAL(big_val * 1 <= small_val, false); + BOOST_CHECK_EQUAL(big_val * 1 >= small_val, true); + BOOST_CHECK_EQUAL(big_val * 1 < small_val, false); + BOOST_CHECK_EQUAL(big_val * 1 > small_val, true); + BOOST_CHECK_EQUAL(big_val * 1 != small_val, true); + BOOST_CHECK_EQUAL(small_val == big_val * 1, false); + BOOST_CHECK_EQUAL(small_val <= big_val * 1, true); + BOOST_CHECK_EQUAL(small_val >= big_val * 1, false); + BOOST_CHECK_EQUAL(small_val < big_val * 1, true); + BOOST_CHECK_EQUAL(small_val > big_val * 1, false); + BOOST_CHECK_EQUAL(small_val != big_val * 1, true); + BOOST_CHECK_EQUAL(big_val * 1 == small_val * 1, false); + BOOST_CHECK_EQUAL(big_val * 1 <= small_val * 1, false); + BOOST_CHECK_EQUAL(big_val * 1 >= small_val * 1, true); + BOOST_CHECK_EQUAL(big_val * 1 < small_val * 1, false); + BOOST_CHECK_EQUAL(big_val * 1 > small_val * 1, true); + BOOST_CHECK_EQUAL(big_val * 1 != small_val * 1, true); + BOOST_CHECK_EQUAL(small_val * 1 == big_val * 1, false); + BOOST_CHECK_EQUAL(small_val * 1 <= big_val * 1, true); + BOOST_CHECK_EQUAL(small_val * 1 >= big_val * 1, false); + BOOST_CHECK_EQUAL(small_val * 1 < big_val * 1, true); + BOOST_CHECK_EQUAL(small_val * 1 > big_val * 1, false); + BOOST_CHECK_EQUAL(small_val * 1 != big_val * 1, true); + + + BOOST_CHECK_EQUAL(small_val + big_val, Big(small_val) + big_val); + BOOST_CHECK_EQUAL(small_val - big_val, Big(small_val) - big_val); + BOOST_CHECK_EQUAL(small_val * big_val, Big(small_val) * big_val); + BOOST_CHECK_EQUAL(small_val / big_val, Big(small_val) / big_val); + BOOST_CHECK_EQUAL(big_val + small_val, big_val + Big(small_val)); + BOOST_CHECK_EQUAL(big_val - small_val, big_val - Big(small_val)); + BOOST_CHECK_EQUAL(big_val * small_val, big_val * Big(small_val)); + BOOST_CHECK_EQUAL(big_val / small_val, big_val / Big(small_val)); + // Again with expression templates, on one the other, or both args: + BOOST_CHECK_EQUAL(small_val + (big_val * 1), Big(small_val) + (big_val * 1)); + BOOST_CHECK_EQUAL(small_val - (big_val * 1), Big(small_val) - (big_val * 1)); + BOOST_CHECK_EQUAL(small_val * (big_val * 1), Big(small_val) * (big_val * 1)); + BOOST_CHECK_EQUAL(small_val / (big_val * 1), Big(small_val) / (big_val * 1)); + BOOST_CHECK_EQUAL((big_val * 1) + small_val, (big_val * 1) + Big(small_val)); + BOOST_CHECK_EQUAL((big_val * 1) - small_val, (big_val * 1) - Big(small_val)); + BOOST_CHECK_EQUAL((big_val * 1) * small_val, (big_val * 1) * Big(small_val)); + BOOST_CHECK_EQUAL((big_val * 1) / small_val, (big_val * 1) / Big(small_val)); + BOOST_CHECK_EQUAL((small_val * 1) + big_val, Big((small_val * 1)) + big_val); + BOOST_CHECK_EQUAL((small_val * 1) - big_val, Big((small_val * 1)) - big_val); + BOOST_CHECK_EQUAL((small_val * 1) * big_val, Big((small_val * 1)) * big_val); + BOOST_CHECK_EQUAL((small_val * 1) / big_val, Big((small_val * 1)) / big_val); + BOOST_CHECK_EQUAL(big_val + (small_val * 1), big_val + Big((small_val * 1))); + BOOST_CHECK_EQUAL(big_val - (small_val * 1), big_val - Big((small_val * 1))); + BOOST_CHECK_EQUAL(big_val * (small_val * 1), big_val * Big((small_val * 1))); + BOOST_CHECK_EQUAL(big_val / (small_val * 1), big_val / Big((small_val * 1))); + BOOST_CHECK_EQUAL((small_val * 1) + (big_val * 1), Big((small_val * 1)) + (big_val * 1)); + BOOST_CHECK_EQUAL((small_val * 1) - (big_val * 1), Big((small_val * 1)) - (big_val * 1)); + BOOST_CHECK_EQUAL((small_val * 1) * (big_val * 1), Big((small_val * 1)) * (big_val * 1)); + BOOST_CHECK_EQUAL((small_val * 1) / (big_val * 1), Big((small_val * 1)) / (big_val * 1)); + BOOST_CHECK_EQUAL((big_val * 1) + (small_val * 1), (big_val * 1) + Big((small_val * 1))); + BOOST_CHECK_EQUAL((big_val * 1) - (small_val * 1), (big_val * 1) - Big((small_val * 1))); + BOOST_CHECK_EQUAL((big_val * 1) * (small_val * 1), (big_val * 1) * Big((small_val * 1))); + BOOST_CHECK_EQUAL((big_val * 1) / (small_val * 1), (big_val * 1) / Big((small_val * 1))); + + big_val = 1; + big_val -= std::numeric_limits::epsilon(); + + BOOST_CHECK_EQUAL(big_val == small_val, false); + BOOST_CHECK_EQUAL(big_val <= small_val, true); + BOOST_CHECK_EQUAL(big_val >= small_val, false); + BOOST_CHECK_EQUAL(big_val < small_val, true); + BOOST_CHECK_EQUAL(big_val > small_val, false); + BOOST_CHECK_EQUAL(big_val != small_val, true); + BOOST_CHECK_EQUAL(small_val == big_val, false); + BOOST_CHECK_EQUAL(small_val <= big_val, false); + BOOST_CHECK_EQUAL(small_val >= big_val, true); + BOOST_CHECK_EQUAL(small_val < big_val, false); + BOOST_CHECK_EQUAL(small_val > big_val, true); + BOOST_CHECK_EQUAL(small_val != big_val, true); + // Again with expression templates, on one the other, or both args: + BOOST_CHECK_EQUAL(big_val == small_val * 1, false); + BOOST_CHECK_EQUAL(big_val <= small_val * 1, true); + BOOST_CHECK_EQUAL(big_val >= small_val * 1, false); + BOOST_CHECK_EQUAL(big_val < small_val * 1, true); + BOOST_CHECK_EQUAL(big_val > small_val * 1, false); + BOOST_CHECK_EQUAL(big_val != small_val * 1, true); + BOOST_CHECK_EQUAL(small_val * 1 == big_val, false); + BOOST_CHECK_EQUAL(small_val * 1 <= big_val, false); + BOOST_CHECK_EQUAL(small_val * 1 >= big_val, true); + BOOST_CHECK_EQUAL(small_val * 1 < big_val, false); + BOOST_CHECK_EQUAL(small_val * 1 > big_val, true); + BOOST_CHECK_EQUAL(small_val * 1 != big_val, true); + BOOST_CHECK_EQUAL(big_val * 1 == small_val, false); + BOOST_CHECK_EQUAL(big_val * 1 <= small_val, true); + BOOST_CHECK_EQUAL(big_val * 1 >= small_val, false); + BOOST_CHECK_EQUAL(big_val * 1 < small_val, true); + BOOST_CHECK_EQUAL(big_val * 1 > small_val, false); + BOOST_CHECK_EQUAL(big_val * 1 != small_val, true); + BOOST_CHECK_EQUAL(small_val == big_val * 1, false); + BOOST_CHECK_EQUAL(small_val <= big_val * 1, false); + BOOST_CHECK_EQUAL(small_val >= big_val * 1, true); + BOOST_CHECK_EQUAL(small_val < big_val * 1, false); + BOOST_CHECK_EQUAL(small_val > big_val * 1, true); + BOOST_CHECK_EQUAL(small_val != big_val * 1, true); + BOOST_CHECK_EQUAL(big_val * 1 == small_val * 1, false); + BOOST_CHECK_EQUAL(big_val * 1 <= small_val * 1, true); + BOOST_CHECK_EQUAL(big_val * 1 >= small_val * 1, false); + BOOST_CHECK_EQUAL(big_val * 1 < small_val * 1, true); + BOOST_CHECK_EQUAL(big_val * 1 > small_val * 1, false); + BOOST_CHECK_EQUAL(big_val * 1 != small_val * 1, true); + BOOST_CHECK_EQUAL(small_val * 1 == big_val * 1, false); + BOOST_CHECK_EQUAL(small_val * 1 <= big_val * 1, false); + BOOST_CHECK_EQUAL(small_val * 1 >= big_val * 1, true); + BOOST_CHECK_EQUAL(small_val * 1 < big_val * 1, false); + BOOST_CHECK_EQUAL(small_val * 1 > big_val * 1, true); + BOOST_CHECK_EQUAL(small_val * 1 != big_val * 1, true); + + BOOST_CHECK_EQUAL(small_val + big_val, Big(small_val) + big_val); + BOOST_CHECK_EQUAL(small_val - big_val, Big(small_val) - big_val); + BOOST_CHECK_EQUAL(small_val * big_val, Big(small_val) * big_val); + BOOST_CHECK_EQUAL(small_val / big_val, Big(small_val) / big_val); + BOOST_CHECK_EQUAL(big_val + small_val, big_val + Big(small_val)); + BOOST_CHECK_EQUAL(big_val - small_val, big_val - Big(small_val)); + BOOST_CHECK_EQUAL(big_val * small_val, big_val * Big(small_val)); + BOOST_CHECK_EQUAL(big_val / small_val, big_val / Big(small_val)); + // Again with expression templates, on one the other, or both args: + BOOST_CHECK_EQUAL(small_val + (big_val * 1), Big(small_val) + (big_val * 1)); + BOOST_CHECK_EQUAL(small_val - (big_val * 1), Big(small_val) - (big_val * 1)); + BOOST_CHECK_EQUAL(small_val * (big_val * 1), Big(small_val) * (big_val * 1)); + BOOST_CHECK_EQUAL(small_val / (big_val * 1), Big(small_val) / (big_val * 1)); + BOOST_CHECK_EQUAL((big_val * 1) + small_val, (big_val * 1) + Big(small_val)); + BOOST_CHECK_EQUAL((big_val * 1) - small_val, (big_val * 1) - Big(small_val)); + BOOST_CHECK_EQUAL((big_val * 1) * small_val, (big_val * 1) * Big(small_val)); + BOOST_CHECK_EQUAL((big_val * 1) / small_val, (big_val * 1) / Big(small_val)); + BOOST_CHECK_EQUAL((small_val * 1) + big_val, Big((small_val * 1)) + big_val); + BOOST_CHECK_EQUAL((small_val * 1) - big_val, Big((small_val * 1)) - big_val); + BOOST_CHECK_EQUAL((small_val * 1) * big_val, Big((small_val * 1)) * big_val); + BOOST_CHECK_EQUAL((small_val * 1) / big_val, Big((small_val * 1)) / big_val); + BOOST_CHECK_EQUAL(big_val + (small_val * 1), big_val + Big((small_val * 1))); + BOOST_CHECK_EQUAL(big_val - (small_val * 1), big_val - Big((small_val * 1))); + BOOST_CHECK_EQUAL(big_val * (small_val * 1), big_val * Big((small_val * 1))); + BOOST_CHECK_EQUAL(big_val / (small_val * 1), big_val / Big((small_val * 1))); + BOOST_CHECK_EQUAL((small_val * 1) + (big_val * 1), Big((small_val * 1)) + (big_val * 1)); + BOOST_CHECK_EQUAL((small_val * 1) - (big_val * 1), Big((small_val * 1)) - (big_val * 1)); + BOOST_CHECK_EQUAL((small_val * 1) * (big_val * 1), Big((small_val * 1)) * (big_val * 1)); + BOOST_CHECK_EQUAL((small_val * 1) / (big_val * 1), Big((small_val * 1)) / (big_val * 1)); + BOOST_CHECK_EQUAL((big_val * 1) + (small_val * 1), (big_val * 1) + Big((small_val * 1))); + BOOST_CHECK_EQUAL((big_val * 1) - (small_val * 1), (big_val * 1) - Big((small_val * 1))); + BOOST_CHECK_EQUAL((big_val * 1) * (small_val * 1), (big_val * 1) * Big((small_val * 1))); + BOOST_CHECK_EQUAL((big_val * 1) / (small_val * 1), (big_val * 1) / Big((small_val * 1))); +} + +#endif // BOOST_MATH_TEST_MIXED_HPP diff --git a/test/test_mixed_cpp_bin_float.cpp b/test/test_mixed_cpp_bin_float.cpp new file mode 100644 index 00000000..3ec03df0 --- /dev/null +++ b/test/test_mixed_cpp_bin_float.cpp @@ -0,0 +1,33 @@ +/////////////////////////////////////////////////////////////// +// Copyright 2012 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 "test_mixed.hpp" + +int main() +{ + try{ + typedef boost::multiprecision::number, boost::multiprecision::et_on> big_type1; + typedef boost::multiprecision::number, boost::multiprecision::et_on> small_type1; + typedef boost::multiprecision::number, boost::multiprecision::et_off> big_type2; + typedef boost::multiprecision::number, boost::multiprecision::et_off> small_type2; + + test(); + test(); + test(); + test(); + } + catch(const std::exception& e) + { + std::cout << "Failed with unexpected exception: " << e.what() << std::endl; + return 1; + } + return boost::report_errors(); +} + diff --git a/test/test_mixed_cpp_dec_float.cpp b/test/test_mixed_cpp_dec_float.cpp new file mode 100644 index 00000000..6582630e --- /dev/null +++ b/test/test_mixed_cpp_dec_float.cpp @@ -0,0 +1,33 @@ +/////////////////////////////////////////////////////////////// +// Copyright 2012 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 "test_mixed.hpp" + +int main() +{ + try{ + typedef boost::multiprecision::number, boost::multiprecision::et_on> big_type1; + typedef boost::multiprecision::number, boost::multiprecision::et_on> small_type1; + typedef boost::multiprecision::number, boost::multiprecision::et_off> big_type2; + typedef boost::multiprecision::number, boost::multiprecision::et_off> small_type2; + + test(); + test(); + test(); + test(); + } + catch(const std::exception& e) + { + std::cout << "Failed with unexpected exception: " << e.what() << std::endl; + return 1; + } + return boost::report_errors(); +} + diff --git a/test/test_mixed_mpf_float.cpp b/test/test_mixed_mpf_float.cpp new file mode 100644 index 00000000..694d77ff --- /dev/null +++ b/test/test_mixed_mpf_float.cpp @@ -0,0 +1,33 @@ +/////////////////////////////////////////////////////////////// +// Copyright 2012 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 "test_mixed.hpp" + +int main() +{ + try{ + typedef boost::multiprecision::number, boost::multiprecision::et_on> big_type1; + typedef boost::multiprecision::number, boost::multiprecision::et_on> small_type1; + typedef boost::multiprecision::number, boost::multiprecision::et_off> big_type2; + typedef boost::multiprecision::number, boost::multiprecision::et_off> small_type2; + + test(); + test(); + test(); + test(); + } + catch(const std::exception& e) + { + std::cout << "Failed with unexpected exception: " << e.what() << std::endl; + return 1; + } + return boost::report_errors(); +} + diff --git a/test/test_mixed_mpfr_float.cpp b/test/test_mixed_mpfr_float.cpp new file mode 100644 index 00000000..4cdc4066 --- /dev/null +++ b/test/test_mixed_mpfr_float.cpp @@ -0,0 +1,33 @@ +/////////////////////////////////////////////////////////////// +// Copyright 2012 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 "test_mixed.hpp" + +int main() +{ + try{ + typedef boost::multiprecision::number, boost::multiprecision::et_on> big_type1; + typedef boost::multiprecision::number, boost::multiprecision::et_on> small_type1; + typedef boost::multiprecision::number, boost::multiprecision::et_off> big_type2; + typedef boost::multiprecision::number, boost::multiprecision::et_off> small_type2; + + test(); + test(); + test(); + test(); + } + catch(const std::exception& e) + { + std::cout << "Failed with unexpected exception: " << e.what() << std::endl; + return 1; + } + return boost::report_errors(); +} + From b94ddb0286d722bb3c931742342185bdcf4f7eb2 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Mon, 1 Jun 2015 19:07:02 +0100 Subject: [PATCH 17/33] Add missing test case. --- test/test_checked_mixed_cpp_int.cpp | 96 +++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 test/test_checked_mixed_cpp_int.cpp diff --git a/test/test_checked_mixed_cpp_int.cpp b/test/test_checked_mixed_cpp_int.cpp new file mode 100644 index 00000000..473af9a2 --- /dev/null +++ b/test/test_checked_mixed_cpp_int.cpp @@ -0,0 +1,96 @@ +/////////////////////////////////////////////////////////////// +// Copyright 2012 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 "test.hpp" + +template +void check_result_type(const T&, const U&) +{ + BOOST_CHECK(0); +} + +void check_result_type(const boost::multiprecision::checked_int1024_t&, const boost::multiprecision::checked_int1024_t&){} + +int main() +{ + try{ + typedef boost::multiprecision::checked_int1024_t big_type; + typedef boost::multiprecision::checked_int512_t small_type; + typedef boost::multiprecision::number, boost::multiprecision::et_off> little_type; + + big_type big_val = (big_type(1) << 1000) + 1; + small_type small_val = 1; + little_type little_val = 1; + + check_result_type(big_val, big_val + small_val); + check_result_type(big_val, big_val - small_val); + check_result_type(big_val, big_val * small_val); + check_result_type(big_val, big_val / small_val); + check_result_type(big_val, big_val | small_val); + check_result_type(big_val, big_val & small_val); + check_result_type(big_val, big_val ^ small_val); + check_result_type(big_val, small_val + big_val); + check_result_type(big_val, small_val - big_val); + check_result_type(big_val, small_val * big_val); + check_result_type(big_val, small_val / big_val); + check_result_type(big_val, small_val | big_val); + check_result_type(big_val, small_val & big_val); + check_result_type(big_val, small_val ^ big_val); + + + check_result_type(big_val, big_val + little_val); + check_result_type(big_val, big_val - little_val); + check_result_type(big_val, big_val * little_val); + check_result_type(big_val, big_val / little_val); + check_result_type(big_val, big_val | little_val); + check_result_type(big_val, big_val & little_val); + check_result_type(big_val, big_val ^ little_val); + check_result_type(big_val, little_val + big_val); + check_result_type(big_val, little_val - big_val); + check_result_type(big_val, little_val * big_val); + check_result_type(big_val, little_val / big_val); + check_result_type(big_val, little_val | big_val); + check_result_type(big_val, little_val & big_val); + check_result_type(big_val, little_val ^ big_val); + + BOOST_CHECK_EQUAL(big_val == small_val, false); + BOOST_CHECK_EQUAL(big_val <= small_val, false); + BOOST_CHECK_EQUAL(big_val >= small_val, true); + BOOST_CHECK_EQUAL(big_val < small_val, false); + BOOST_CHECK_EQUAL(big_val > small_val, true); + BOOST_CHECK_EQUAL(big_val != small_val, true); + BOOST_CHECK_EQUAL(small_val == big_val, false); + BOOST_CHECK_EQUAL(small_val <= big_val, true); + BOOST_CHECK_EQUAL(small_val >= big_val, false); + BOOST_CHECK_EQUAL(small_val < big_val, true); + BOOST_CHECK_EQUAL(small_val > big_val, false); + BOOST_CHECK_EQUAL(small_val != big_val, true); + + BOOST_CHECK_EQUAL(big_val == little_val, false); + BOOST_CHECK_EQUAL(big_val <= little_val, false); + BOOST_CHECK_EQUAL(big_val >= little_val, true); + BOOST_CHECK_EQUAL(big_val < little_val, false); + BOOST_CHECK_EQUAL(big_val > little_val, true); + BOOST_CHECK_EQUAL(big_val != little_val, true); + BOOST_CHECK_EQUAL(little_val == big_val, false); + BOOST_CHECK_EQUAL(little_val <= big_val, true); + BOOST_CHECK_EQUAL(little_val >= big_val, false); + BOOST_CHECK_EQUAL(little_val < big_val, true); + BOOST_CHECK_EQUAL(little_val > big_val, false); + BOOST_CHECK_EQUAL(little_val != big_val, true); + } + catch(const std::exception& e) + { + std::cout << "Failed with unexpected exception: " << e.what() << std::endl; + return 1; + } + return boost::report_errors(); +} + From 8edcd89f39785103db1f3b77084d594cc9673e87 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Mon, 1 Jun 2015 19:07:28 +0100 Subject: [PATCH 18/33] Split some tests up. --- test/Jamfile.v2 | 2 + test/concepts/sf_concept_check_beta.cpp | 129 +++++++++++++++++++++++ test/concepts/sf_concept_check_gamma.cpp | 16 +-- test/test_arithmetic_mpz.cpp | 1 - test/test_arithmetic_mpz_rat.cpp | 20 ++++ test/test_arithmetic_tommath.cpp | 1 - test/test_arithmetic_tommath_rat.cpp | 22 ++++ 7 files changed, 174 insertions(+), 17 deletions(-) create mode 100644 test/concepts/sf_concept_check_beta.cpp create mode 100644 test/test_arithmetic_mpz_rat.cpp create mode 100644 test/test_arithmetic_tommath_rat.cpp diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index fd6ce7c4..16093110 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -70,6 +70,7 @@ run test_arithmetic_cpp_bin_float_3.cpp ; run test_arithmetic_mpf_50.cpp gmp : : : [ check-target-builds ../config//has_gmp : : no ] ; run test_arithmetic_mpf.cpp gmp : : : [ check-target-builds ../config//has_gmp : : no ] ; run test_arithmetic_mpz.cpp gmp : : : [ check-target-builds ../config//has_gmp : : no ] ; +run test_arithmetic_mpz_rat.cpp gmp : : : [ check-target-builds ../config//has_gmp : : no ] ; run test_arithmetic_mpz_br.cpp gmp : : : [ check-target-builds ../config//has_gmp : : no ] ; run test_arithmetic_mpq.cpp gmp : : : [ check-target-builds ../config//has_gmp : : no ] ; @@ -78,6 +79,7 @@ run test_arithmetic_mpfr_50.cpp mpfr gmp : : : [ check-target-builds ../config// run test_arithmetic_mpfr_50_static.cpp mpfr gmp : : : [ check-target-builds ../config//has_mpfr : : no ] ; run test_arithmetic_tommath.cpp $(TOMMATH) : : : [ check-target-builds ../config//has_tommath : : no ] ; +run test_arithmetic_tommath_rat.cpp $(TOMMATH) : : : [ check-target-builds ../config//has_tommath : : no ] ; run test_arithmetic_tommath_br.cpp $(TOMMATH) : : : [ check-target-builds ../config//has_tommath : : no ] ; run test_arithmetic_cpp_int_1.cpp ; diff --git a/test/concepts/sf_concept_check_beta.cpp b/test/concepts/sf_concept_check_beta.cpp new file mode 100644 index 00000000..c1e6aa18 --- /dev/null +++ b/test/concepts/sf_concept_check_beta.cpp @@ -0,0 +1,129 @@ +// Copyright John Maddock 2012. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// +// This tests that cpp_dec_float_50 meets our +// conceptual requirements when used with Boost.Math. +// +#ifdef _MSC_VER +# define _SCL_SECURE_NO_WARNINGS +# pragma warning(disable:4800) +# pragma warning(disable:4512) +# pragma warning(disable:4127) +# pragma warning(disable:4512) +# pragma warning(disable:4503) // decorated name length exceeded, name was truncated +#endif + +#include + +#if !defined(TEST_MPF_50) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) \ + && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR_50)\ + && !defined(TEST_MPFR_6) && !defined(TEST_MPFR_15) && !defined(TEST_MPFR_17) \ + && !defined(TEST_MPFR_30) && !defined(TEST_CPP_DEC_FLOAT_NO_ET) && !defined(TEST_LOGGED_ADAPTER)\ + && !defined(TEST_CPP_BIN_FLOAT) +# define TEST_MPF_50 +# define TEST_BACKEND +# define TEST_MPZ +# define TEST_MPFR_50 +# define TEST_MPFR_6 +# define TEST_MPFR_15 +# define TEST_MPFR_17 +# define TEST_MPFR_30 +# define TEST_CPP_DEC_FLOAT +# define TEST_CPP_DEC_FLOAT_NO_ET +# define TEST_LOGGED_ADAPTER +# define TEST_CPP_BIN_FLOAT + +#ifdef _MSC_VER +#pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") +#endif +#ifdef __GNUC__ +#pragma warning "CAUTION!!: No backend type specified so testing everything.... this will take some time!!" +#endif + +#endif + +#if defined(TEST_MPF_50) || defined(TEST_MPZ) +#include +#endif +#ifdef TEST_BACKEND +#include +#endif +#if defined(TEST_CPP_DEC_FLOAT) || defined(TEST_CPP_DEC_FLOAT_NO_ET) || defined(TEST_LOGGED_ADAPTER) +#include +#endif +#if defined(TEST_MPFR_50) || defined(TEST_MPFR_6) || defined(TEST_MPFR_15) || defined(TEST_MPFR_17) || defined(TEST_MPFR_30) +#include +#endif +#if defined(TEST_CPP_BIN_FLOAT) +#include +#endif +#ifdef TEST_LOGGED_ADAPTER +#include +#endif + +#include + +template +void test_extra(T) +{ + T v1, v2, v3; + int i; + boost::math::beta(v1, v2); + boost::math::beta(v1, v2, v3); + boost::math::betac(v1, v2, v3); + boost::math::ibeta(v1, v2, v3); + boost::math::ibetac(v1, v2, v3); + boost::math::ibeta_inv(v1, v2, v3); + boost::math::ibetac_inv(v1, v2, v3); + boost::math::ibeta_inva(v1, v2, v3); + boost::math::ibetac_inva(v1, v2, v3); + boost::math::ibeta_invb(v1, v2, v3); + boost::math::ibetac_invb(v1, v2, v3); + boost::math::ibeta_derivative(v1, v2, v3); +} + +void foo() +{ +#ifdef TEST_BACKEND + test_extra(boost::multiprecision::concepts::mp_number_float_architype()); +#endif +#ifdef TEST_MPF_50 + test_extra(boost::multiprecision::mpf_float_50()); +#endif +#ifdef TEST_MPFR_50 + test_extra(boost::multiprecision::mpfr_float_50()); +#endif +#ifdef TEST_MPFR_6 + test_extra(boost::multiprecision::number >()); +#endif +#ifdef TEST_MPFR_15 + test_extra(boost::multiprecision::number >()); +#endif +#ifdef TEST_MPFR_17 + test_extra(boost::multiprecision::number >()); +#endif +#ifdef TEST_MPFR_30 + test_extra(boost::multiprecision::number >()); +#endif +#ifdef TEST_CPP_DEC_FLOAT + test_extra(boost::multiprecision::cpp_dec_float_50()); +#endif +#ifdef TEST_CPP_BIN_FLOAT + test_extra(boost::multiprecision::cpp_bin_float_50()); +#endif +#ifdef TEST_CPP_DEC_FLOAT_NO_ET + test_extra(boost::multiprecision::number, boost::multiprecision::et_off>()); +#endif +#ifdef TEST_LOGGED_ADAPTER + typedef boost::multiprecision::number > > num_t; + test_extra(num_t()); +#endif +} + +int main() +{ + foo(); +} diff --git a/test/concepts/sf_concept_check_gamma.cpp b/test/concepts/sf_concept_check_gamma.cpp index fd07db1c..cad179cf 100644 --- a/test/concepts/sf_concept_check_gamma.cpp +++ b/test/concepts/sf_concept_check_gamma.cpp @@ -84,7 +84,7 @@ void test_extra(T) boost::math::double_factorial(i); boost::math::rising_factorial(v1, i); boost::math::falling_factorial(v1, i); -#ifndef SLOW_COMPILER + boost::math::gamma_p_derivative(v2, v3); boost::math::tgamma(v1, v2); boost::math::tgamma_lower(v1, v2); boost::math::gamma_p(v1, v2); @@ -97,20 +97,6 @@ void test_extra(T) boost::math::erfc(v1); boost::math::erf_inv(v1); boost::math::erfc_inv(v1); - boost::math::beta(v1, v2); - boost::math::beta(v1, v2, v3); - boost::math::betac(v1, v2, v3); - boost::math::ibeta(v1, v2, v3); - boost::math::ibetac(v1, v2, v3); - boost::math::ibeta_inv(v1, v2, v3); - boost::math::ibetac_inv(v1, v2, v3); - boost::math::ibeta_inva(v1, v2, v3); - boost::math::ibetac_inva(v1, v2, v3); - boost::math::ibeta_invb(v1, v2, v3); - boost::math::ibetac_invb(v1, v2, v3); - boost::math::gamma_p_derivative(v2, v3); - boost::math::ibeta_derivative(v1, v2, v3); -#endif } void foo() diff --git a/test/test_arithmetic_mpz.cpp b/test/test_arithmetic_mpz.cpp index b1306d3a..c2df7708 100644 --- a/test/test_arithmetic_mpz.cpp +++ b/test/test_arithmetic_mpz.cpp @@ -15,7 +15,6 @@ int main() { test(); - test > >(); return boost::report_errors(); } diff --git a/test/test_arithmetic_mpz_rat.cpp b/test/test_arithmetic_mpz_rat.cpp new file mode 100644 index 00000000..729039ae --- /dev/null +++ b/test/test_arithmetic_mpz_rat.cpp @@ -0,0 +1,20 @@ +/////////////////////////////////////////////////////////////// +// Copyright 2012 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_arithmetic.hpp" + +int main() +{ + test > >(); + return boost::report_errors(); +} + diff --git a/test/test_arithmetic_tommath.cpp b/test/test_arithmetic_tommath.cpp index 3207001c..75882a17 100644 --- a/test/test_arithmetic_tommath.cpp +++ b/test/test_arithmetic_tommath.cpp @@ -17,7 +17,6 @@ struct is_twos_complement_integer : public boost int main() { test(); - test > >(); return boost::report_errors(); } diff --git a/test/test_arithmetic_tommath_rat.cpp b/test/test_arithmetic_tommath_rat.cpp new file mode 100644 index 00000000..66a44db4 --- /dev/null +++ b/test/test_arithmetic_tommath_rat.cpp @@ -0,0 +1,22 @@ +/////////////////////////////////////////////////////////////// +// Copyright 2012 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 "test_arithmetic.hpp" + +template <> +struct is_twos_complement_integer : public boost::mpl::false_ {}; + +int main() +{ + test > >(); + return boost::report_errors(); +} + From 6d7a27889e1821d6d667438a7fb6e95948ee9663 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Tue, 2 Jun 2015 09:14:16 +0100 Subject: [PATCH 19/33] Fix signed exclusive-bitwise-or to handle carry correctly. See https://svn.boost.org/trac/boost/ticket/11364. --- include/boost/multiprecision/cpp_int/bitwise.hpp | 8 +++++++- test/test_cpp_int.cpp | 8 ++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/include/boost/multiprecision/cpp_int/bitwise.hpp b/include/boost/multiprecision/cpp_int/bitwise.hpp index e18f3569..63d3b639 100644 --- a/include/boost/multiprecision/cpp_int/bitwise.hpp +++ b/include/boost/multiprecision/cpp_int/bitwise.hpp @@ -159,7 +159,6 @@ void bitwise_op( // if(static_cast(next_limb) < 0) { - result.sign(true); double_limb_type carry = 1; for(unsigned i = 0; i < x; ++i) { @@ -167,6 +166,13 @@ void bitwise_op( pr[i] = static_cast(carry); carry >>= CppInt1::limb_bits; } + if(carry) + { + result.resize(x + 1, x); + if(result.size() > x) + result.limbs()[x] = static_cast(carry); + } + result.sign(true); } else result.sign(false); diff --git a/test/test_cpp_int.cpp b/test/test_cpp_int.cpp index 8172ec74..1187ab33 100644 --- a/test/test_cpp_int.cpp +++ b/test/test_cpp_int.cpp @@ -486,6 +486,14 @@ struct tester a = 1; a = 0 % test_type(25); BOOST_CHECK_EQUAL(a, 0); +#ifndef TEST2 + // https://svn.boost.org/trac/boost/ticket/11364 + a = 0xfffffffeu; + b = -2; + c = a ^ b; + test_type d = ~(a ^ ~b); + BOOST_CHECK_EQUAL(c, d); +#endif } void test() From 82c8c2692c3e3cb569490035146530ba0ca50072 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Tue, 2 Jun 2015 13:41:44 +0100 Subject: [PATCH 20/33] Fix typecast. --- include/boost/multiprecision/mpfr.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/multiprecision/mpfr.hpp b/include/boost/multiprecision/mpfr.hpp index ac7699c0..dcf0044c 100644 --- a/include/boost/multiprecision/mpfr.hpp +++ b/include/boost/multiprecision/mpfr.hpp @@ -134,7 +134,7 @@ struct mpfr_float_imp 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)))); + mpfr_init2(t, (std::max)(static_cast(std::numeric_limits::digits), static_cast(multiprecision::detail::digits10_2_2(digits10)))); mpfr_set_ui(m_data, 0, GMP_RNDN); while(i) { From 1c3dae17ad1fff116ec330f744e06206dc2c2691 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Tue, 2 Jun 2015 18:07:11 +0100 Subject: [PATCH 21/33] Fix issue with ambiguous conversions. --- include/boost/multiprecision/traits/is_backend.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/multiprecision/traits/is_backend.hpp b/include/boost/multiprecision/traits/is_backend.hpp index bd9458c9..bb332b3e 100644 --- a/include/boost/multiprecision/traits/is_backend.hpp +++ b/include/boost/multiprecision/traits/is_backend.hpp @@ -50,7 +50,7 @@ namespace boost{ namespace multiprecision{ namespace detail{ template struct is_second_backend_imp{ static const bool value = false; }; template - struct is_second_backend_imp{ static const bool value = is_convertible >::value || is_convertible >::value; }; + struct is_second_backend_imp{ static const bool value = (is_convertible >::value || is_convertible >::value) && !is_first_backend::value; }; template struct is_second_backend : is_second_backend_imp::value, T, U> {}; From 85b60a1e8171aa3d357724139322dd7d8f8fa6b3 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Tue, 2 Jun 2015 18:25:32 +0100 Subject: [PATCH 22/33] Add missing #include. --- include/boost/multiprecision/traits/is_backend.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/boost/multiprecision/traits/is_backend.hpp b/include/boost/multiprecision/traits/is_backend.hpp index bb332b3e..9b23c866 100644 --- a/include/boost/multiprecision/traits/is_backend.hpp +++ b/include/boost/multiprecision/traits/is_backend.hpp @@ -7,6 +7,7 @@ #define BOOST_MP_IS_BACKEND_HPP #include +#include #include #include From db6b075e7a33a704bddb6dc88c7df524e800ba2e Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Tue, 2 Jun 2015 18:27:13 +0100 Subject: [PATCH 23/33] Remove unneeded typedef. --- include/boost/multiprecision/gmp.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/include/boost/multiprecision/gmp.hpp b/include/boost/multiprecision/gmp.hpp index 1442d8a7..6351f7ea 100644 --- a/include/boost/multiprecision/gmp.hpp +++ b/include/boost/multiprecision/gmp.hpp @@ -1695,7 +1695,6 @@ inline typename enable_if, Integer>::type eval_integer_modu template inline typename enable_if, Integer>::type eval_integer_modulus(const gmp_int& x, Integer val) { - typedef typename make_unsigned::type unsigned_type; return eval_integer_modulus(x, boost::multiprecision::detail::unsigned_abs(val)); } inline void eval_powm(gmp_int& result, const gmp_int& base, const gmp_int& p, const gmp_int& m) From 9cd23ea8bda66b61acc0cdfed5c2df8ed8bb3c75 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Wed, 3 Jun 2015 18:51:14 +0100 Subject: [PATCH 24/33] Fix signed/unsigned comparison. --- include/boost/multiprecision/detail/functions/pow.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/multiprecision/detail/functions/pow.hpp b/include/boost/multiprecision/detail/functions/pow.hpp index 44c0b38e..b58d6b07 100644 --- a/include/boost/multiprecision/detail/functions/pow.hpp +++ b/include/boost/multiprecision/detail/functions/pow.hpp @@ -165,7 +165,7 @@ void hyp1F0(T& H1F0, const T& a, const T& x) si_type n; T term, part; - static const unsigned series_limit = + static const si_type series_limit = boost::multiprecision::detail::digits2 >::value < 100 ? 100 : boost::multiprecision::detail::digits2 >::value; // Series expansion of hyperg_1f0(a; ; x). From 2d8d8528b766bb01e3b04cc7f20be2ee28b3b6f1 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Wed, 3 Jun 2015 18:51:41 +0100 Subject: [PATCH 25/33] Remove unused typedef. --- include/boost/multiprecision/tommath.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/include/boost/multiprecision/tommath.hpp b/include/boost/multiprecision/tommath.hpp index 65fb667a..9c373443 100644 --- a/include/boost/multiprecision/tommath.hpp +++ b/include/boost/multiprecision/tommath.hpp @@ -640,7 +640,6 @@ inline typename enable_if, Integer>::type eval_integer_modu template inline typename enable_if, Integer>::type eval_integer_modulus(const tommath_int& x, Integer val) { - typedef typename make_unsigned::type unsigned_type; return eval_integer_modulus(x, boost::multiprecision::detail::unsigned_abs(val)); } From 7333ad455df8578bcf3c72897cffa52f6afb5fb7 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Wed, 3 Jun 2015 18:52:33 +0100 Subject: [PATCH 26/33] Simplify code so msvc-12 can cope. Errors only show up in certain complex cases, most notably in Boost.Random's test suite. --- .../multiprecision/detail/number_compare.hpp | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/include/boost/multiprecision/detail/number_compare.hpp b/include/boost/multiprecision/detail/number_compare.hpp index 3ac34b79..e9e510d3 100644 --- a/include/boost/multiprecision/detail/number_compare.hpp +++ b/include/boost/multiprecision/detail/number_compare.hpp @@ -16,23 +16,34 @@ namespace boost{ namespace multiprecision{ namespace default_ops{ +// +// The dispatching mechanism used here to deal with differently typed arguments +// could be better replaced with enable_if overloads, but that breaks MSVC-12 +// under strange and hard to reproduce circumstances. +// template inline bool eval_eq(const B& a, const B& b) { return a.compare(b) == 0; } template -inline typename enable_if_c::value, bool>::type eval_eq(const T& a, const U& b) +inline bool eval_eq_imp(const T& a, const U& b, const mpl::true_&) { typename boost::multiprecision::detail::number_from_backend::type t(b); return eval_eq(a, t.backend()); } template -inline typename enable_if_c::value, bool>::type eval_eq(const T& a, const U& b) +inline bool eval_eq_imp(const T& a, const U& b, const mpl::false_&) { typename boost::multiprecision::detail::number_from_backend::type t(a); return eval_eq(t.backend(), b); } +template +inline bool eval_eq(const T& a, const U& b) +{ + typedef mpl::bool_::value> tag_type; + return eval_eq_imp(a, b, tag_type()); +} template inline bool eval_lt(const B& a, const B& b) @@ -40,17 +51,23 @@ inline bool eval_lt(const B& a, const B& b) return a.compare(b) < 0; } template -inline typename enable_if_c::value, bool>::type eval_lt(const T& a, const U& b) +inline bool eval_lt_imp(const T& a, const U& b, const mpl::true_&) { typename boost::multiprecision::detail::number_from_backend::type t(b); return eval_lt(a, t.backend()); } template -inline typename enable_if_c::value, bool>::type eval_lt(const T& a, const U& b) +inline bool eval_lt_imp(const T& a, const U& b, const mpl::false_&) { typename boost::multiprecision::detail::number_from_backend::type t(a); return eval_lt(t.backend(), b); } +template +inline bool eval_lt(const T& a, const U& b) +{ + typedef mpl::bool_::value> tag_type; + return eval_lt_imp(a, b, tag_type()); +} template inline bool eval_gt(const B& a, const B& b) @@ -58,17 +75,23 @@ inline bool eval_gt(const B& a, const B& b) return a.compare(b) > 0; } template -inline typename enable_if_c::value, bool>::type eval_gt(const T& a, const U& b) +inline bool eval_gt_imp(const T& a, const U& b, const mpl::true_&) { typename boost::multiprecision::detail::number_from_backend::type t(b); return eval_gt(a, t.backend()); } template -inline typename enable_if_c::value, bool>::type eval_gt(const T& a, const U& b) +inline bool eval_gt_imp(const T& a, const U& b, const mpl::false_&) { typename boost::multiprecision::detail::number_from_backend::type t(a); return eval_gt(t.backend(), b); } +template +inline bool eval_gt(const T& a, const U& b) +{ + typedef mpl::bool_::value> tag_type; + return eval_gt_imp(a, b, tag_type()); +} } // namespace default_ops From fec524f93a1112dc0c85b039e52cdbe719af01e9 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Thu, 4 Jun 2015 09:06:14 +0100 Subject: [PATCH 27/33] Split test up again - still too big! --- test/concepts/sf_concept_check_beta.cpp | 6 -- test/concepts/sf_concept_check_beta_2.cpp | 123 ++++++++++++++++++++++ 2 files changed, 123 insertions(+), 6 deletions(-) create mode 100644 test/concepts/sf_concept_check_beta_2.cpp diff --git a/test/concepts/sf_concept_check_beta.cpp b/test/concepts/sf_concept_check_beta.cpp index c1e6aa18..a1084446 100644 --- a/test/concepts/sf_concept_check_beta.cpp +++ b/test/concepts/sf_concept_check_beta.cpp @@ -76,12 +76,6 @@ void test_extra(T) boost::math::betac(v1, v2, v3); boost::math::ibeta(v1, v2, v3); boost::math::ibetac(v1, v2, v3); - boost::math::ibeta_inv(v1, v2, v3); - boost::math::ibetac_inv(v1, v2, v3); - boost::math::ibeta_inva(v1, v2, v3); - boost::math::ibetac_inva(v1, v2, v3); - boost::math::ibeta_invb(v1, v2, v3); - boost::math::ibetac_invb(v1, v2, v3); boost::math::ibeta_derivative(v1, v2, v3); } diff --git a/test/concepts/sf_concept_check_beta_2.cpp b/test/concepts/sf_concept_check_beta_2.cpp new file mode 100644 index 00000000..d419796f --- /dev/null +++ b/test/concepts/sf_concept_check_beta_2.cpp @@ -0,0 +1,123 @@ +// Copyright John Maddock 2012. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// +// This tests that cpp_dec_float_50 meets our +// conceptual requirements when used with Boost.Math. +// +#ifdef _MSC_VER +# define _SCL_SECURE_NO_WARNINGS +# pragma warning(disable:4800) +# pragma warning(disable:4512) +# pragma warning(disable:4127) +# pragma warning(disable:4512) +# pragma warning(disable:4503) // decorated name length exceeded, name was truncated +#endif + +#include + +#if !defined(TEST_MPF_50) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) \ + && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR_50)\ + && !defined(TEST_MPFR_6) && !defined(TEST_MPFR_15) && !defined(TEST_MPFR_17) \ + && !defined(TEST_MPFR_30) && !defined(TEST_CPP_DEC_FLOAT_NO_ET) && !defined(TEST_LOGGED_ADAPTER)\ + && !defined(TEST_CPP_BIN_FLOAT) +# define TEST_MPF_50 +# define TEST_BACKEND +# define TEST_MPZ +# define TEST_MPFR_50 +# define TEST_MPFR_6 +# define TEST_MPFR_15 +# define TEST_MPFR_17 +# define TEST_MPFR_30 +# define TEST_CPP_DEC_FLOAT +# define TEST_CPP_DEC_FLOAT_NO_ET +# define TEST_LOGGED_ADAPTER +# define TEST_CPP_BIN_FLOAT + +#ifdef _MSC_VER +#pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") +#endif +#ifdef __GNUC__ +#pragma warning "CAUTION!!: No backend type specified so testing everything.... this will take some time!!" +#endif + +#endif + +#if defined(TEST_MPF_50) || defined(TEST_MPZ) +#include +#endif +#ifdef TEST_BACKEND +#include +#endif +#if defined(TEST_CPP_DEC_FLOAT) || defined(TEST_CPP_DEC_FLOAT_NO_ET) || defined(TEST_LOGGED_ADAPTER) +#include +#endif +#if defined(TEST_MPFR_50) || defined(TEST_MPFR_6) || defined(TEST_MPFR_15) || defined(TEST_MPFR_17) || defined(TEST_MPFR_30) +#include +#endif +#if defined(TEST_CPP_BIN_FLOAT) +#include +#endif +#ifdef TEST_LOGGED_ADAPTER +#include +#endif + +#include + +template +void test_extra(T) +{ + T v1, v2, v3; + int i; + boost::math::ibeta_inv(v1, v2, v3); + boost::math::ibetac_inv(v1, v2, v3); + boost::math::ibeta_inva(v1, v2, v3); + boost::math::ibetac_inva(v1, v2, v3); + boost::math::ibeta_invb(v1, v2, v3); + boost::math::ibetac_invb(v1, v2, v3); +} + +void foo() +{ +#ifdef TEST_BACKEND + test_extra(boost::multiprecision::concepts::mp_number_float_architype()); +#endif +#ifdef TEST_MPF_50 + test_extra(boost::multiprecision::mpf_float_50()); +#endif +#ifdef TEST_MPFR_50 + test_extra(boost::multiprecision::mpfr_float_50()); +#endif +#ifdef TEST_MPFR_6 + test_extra(boost::multiprecision::number >()); +#endif +#ifdef TEST_MPFR_15 + test_extra(boost::multiprecision::number >()); +#endif +#ifdef TEST_MPFR_17 + test_extra(boost::multiprecision::number >()); +#endif +#ifdef TEST_MPFR_30 + test_extra(boost::multiprecision::number >()); +#endif +#ifdef TEST_CPP_DEC_FLOAT + test_extra(boost::multiprecision::cpp_dec_float_50()); +#endif +#ifdef TEST_CPP_BIN_FLOAT + test_extra(boost::multiprecision::cpp_bin_float_50()); +#endif +#ifdef TEST_CPP_DEC_FLOAT_NO_ET + test_extra(boost::multiprecision::number, boost::multiprecision::et_off>()); +#endif +#ifdef TEST_LOGGED_ADAPTER + typedef boost::multiprecision::number > > num_t; + test_extra(num_t()); +#endif +} + +int main() +{ + foo(); +} From f866903e9d389da4fb6fe5bfaa2feaa5bbda645a Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Thu, 4 Jun 2015 13:17:29 +0100 Subject: [PATCH 28/33] Fix test failures for special functions. --- test/Jamfile.v2 | 14 +++++ test/math/instances/Jamfile.v2 | 1 + test/math/test_carlson_1.cpp | 63 +++++++++++++++++++ .../{test_carlson.cpp => test_carlson_2.cpp} | 1 + test/math/test_carlson_3.cpp | 62 ++++++++++++++++++ test/math/test_carlson_4.cpp | 62 ++++++++++++++++++ test/math/test_digamma.cpp | 7 +++ test/math/test_ellint_3.cpp | 7 +++ 8 files changed, 217 insertions(+) create mode 100644 test/math/test_carlson_1.cpp rename test/math/{test_carlson.cpp => test_carlson_2.cpp} (99%) create mode 100644 test/math/test_carlson_3.cpp create mode 100644 test/math/test_carlson_4.cpp diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 16093110..359ba2d1 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -698,7 +698,9 @@ if $(enable-specfun) TEST_MPFR_50 speed BOOST_ALL_NO_LIB + BOOST_OPTIONAL_USE_OLD_DEFINITION_OF_NONE msvc:-bigobj + ../../math/include_private release : $(source:B)_mpfr ; run $(source) gmp @@ -712,7 +714,9 @@ if $(enable-specfun) speed TEST_MPF_50 BOOST_ALL_NO_LIB + BOOST_OPTIONAL_USE_OLD_DEFINITION_OF_NONE msvc:-bigobj + ../../math/include_private release : $(source:B)_mpf ; run $(source) /boost/test//boost_unit_test_framework/static @@ -723,8 +727,10 @@ if $(enable-specfun) : # requirements TEST_CPP_DEC_FLOAT BOOST_ALL_NO_LIB + BOOST_OPTIONAL_USE_OLD_DEFINITION_OF_NONE speed msvc:-bigobj + ../../math/include_private release : $(source:B)_cpp_dec_float ; run $(source) /boost/test//boost_unit_test_framework/static @@ -735,8 +741,10 @@ if $(enable-specfun) : # requirements TEST_CPP_BIN_FLOAT BOOST_ALL_NO_LIB + BOOST_OPTIONAL_USE_OLD_DEFINITION_OF_NONE speed msvc:-bigobj + ../../math/include_private release : $(source:B)_cpp_bin_float ; run $(source) quadmath @@ -750,7 +758,9 @@ if $(enable-specfun) speed TEST_FLOAT128 BOOST_ALL_NO_LIB + BOOST_OPTIONAL_USE_OLD_DEFINITION_OF_NONE msvc:-bigobj + ../../math/include_private release : $(source:B)_float128 ; run $(source) @@ -764,7 +774,9 @@ if $(enable-specfun) speed TEST_FLOAT128 BOOST_ALL_NO_LIB + BOOST_OPTIONAL_USE_OLD_DEFINITION_OF_NONE msvc:-bigobj + ../../math/include_private release : $(source:B)_intel_quad ; } @@ -782,8 +794,10 @@ if $(enable-specfun) : # requirements speed BOOST_ALL_NO_LIB + BOOST_OPTIONAL_USE_OLD_DEFINITION_OF_NONE msvc:-bigobj [ check-target-builds ../config//has_mpfr : TEST_MPFR gmp mpfr : ] + ../../math/include_private release ; } } diff --git a/test/math/instances/Jamfile.v2 b/test/math/instances/Jamfile.v2 index 9e6aa472..a01af496 100644 --- a/test/math/instances/Jamfile.v2 +++ b/test/math/instances/Jamfile.v2 @@ -33,6 +33,7 @@ project : requirements gcc:-Wall gcc:-Wextra intel:SLOW_COMPILER + BOOST_OPTIONAL_USE_OLD_DEFINITION_OF_NONE ; lib gmp : : $(gmp_path) ; diff --git a/test/math/test_carlson_1.cpp b/test/math/test_carlson_1.cpp new file mode 100644 index 00000000..4309a5b9 --- /dev/null +++ b/test/math/test_carlson_1.cpp @@ -0,0 +1,63 @@ +/////////////////////////////////////////////////////////////// +// Copyright 2011 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_ + +#include "setup.hpp" +#include "table_type.hpp" +#define TEST_UDT +#define TEST1 + +#include +#include +#include "libs/math/test/test_carlson.hpp" + +void expected_results() +{ + // + // Define the max and mean errors expected for + // various compilers and platforms. + // + add_expected_result( + ".*", // compiler + ".*", // stdlib + ".*", // platform + ".*", // test type(s) + ".*RJ.*", // test data group + ".*", 2700, 250); // test function + add_expected_result( + ".*", // compiler + ".*", // stdlib + ".*", // platform + ".*", // test type(s) + ".*", // test data group + ".*", 40, 20); // test function + // + // Finish off by printing out the compiler/stdlib/platform names, + // we do this to make it easier to mark up expected error rates. + // + std::cout << "Tests run with " << BOOST_COMPILER << ", " + << BOOST_STDLIB << ", " << BOOST_PLATFORM << std::endl; +} + +template +void test(T t, const char* p) +{ + test_spots(t, p); +} + +BOOST_AUTO_TEST_CASE( test_main ) +{ + using namespace boost::multiprecision; + expected_results(); + // + // Test at: + // 18 decimal digits: tests 80-bit long double approximations + // 30 decimal digits: tests 128-bit long double approximations + // 35 decimal digits: tests arbitrary precision code + // + ALL_TESTS +} + + + diff --git a/test/math/test_carlson.cpp b/test/math/test_carlson_2.cpp similarity index 99% rename from test/math/test_carlson.cpp rename to test/math/test_carlson_2.cpp index 58cbee63..933108d9 100644 --- a/test/math/test_carlson.cpp +++ b/test/math/test_carlson_2.cpp @@ -6,6 +6,7 @@ #include "setup.hpp" #include "table_type.hpp" #define TEST_UDT +#define TEST2 #include #include "libs/math/test/test_carlson.hpp" diff --git a/test/math/test_carlson_3.cpp b/test/math/test_carlson_3.cpp new file mode 100644 index 00000000..a4b723a6 --- /dev/null +++ b/test/math/test_carlson_3.cpp @@ -0,0 +1,62 @@ +/////////////////////////////////////////////////////////////// +// Copyright 2011 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_ + +#include "setup.hpp" +#include "table_type.hpp" +#define TEST_UDT +#define TEST3 + +#include +#include "libs/math/test/test_carlson.hpp" + +void expected_results() +{ + // + // Define the max and mean errors expected for + // various compilers and platforms. + // + add_expected_result( + ".*", // compiler + ".*", // stdlib + ".*", // platform + ".*", // test type(s) + ".*RJ.*", // test data group + ".*", 2700, 250); // test function + add_expected_result( + ".*", // compiler + ".*", // stdlib + ".*", // platform + ".*", // test type(s) + ".*", // test data group + ".*", 40, 20); // test function + // + // Finish off by printing out the compiler/stdlib/platform names, + // we do this to make it easier to mark up expected error rates. + // + std::cout << "Tests run with " << BOOST_COMPILER << ", " + << BOOST_STDLIB << ", " << BOOST_PLATFORM << std::endl; +} + +template +void test(T t, const char* p) +{ + test_spots(t, p); +} + +BOOST_AUTO_TEST_CASE( test_main ) +{ + using namespace boost::multiprecision; + expected_results(); + // + // Test at: + // 18 decimal digits: tests 80-bit long double approximations + // 30 decimal digits: tests 128-bit long double approximations + // 35 decimal digits: tests arbitrary precision code + // + ALL_TESTS +} + + + diff --git a/test/math/test_carlson_4.cpp b/test/math/test_carlson_4.cpp new file mode 100644 index 00000000..abea8163 --- /dev/null +++ b/test/math/test_carlson_4.cpp @@ -0,0 +1,62 @@ +/////////////////////////////////////////////////////////////// +// Copyright 2011 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_ + +#include "setup.hpp" +#include "table_type.hpp" +#define TEST_UDT +#define TEST4 + +#include +#include "libs/math/test/test_carlson.hpp" + +void expected_results() +{ + // + // Define the max and mean errors expected for + // various compilers and platforms. + // + add_expected_result( + ".*", // compiler + ".*", // stdlib + ".*", // platform + ".*", // test type(s) + ".*RJ.*", // test data group + ".*", 2700, 250); // test function + add_expected_result( + ".*", // compiler + ".*", // stdlib + ".*", // platform + ".*", // test type(s) + ".*", // test data group + ".*", 40, 20); // test function + // + // Finish off by printing out the compiler/stdlib/platform names, + // we do this to make it easier to mark up expected error rates. + // + std::cout << "Tests run with " << BOOST_COMPILER << ", " + << BOOST_STDLIB << ", " << BOOST_PLATFORM << std::endl; +} + +template +void test(T t, const char* p) +{ + test_spots(t, p); +} + +BOOST_AUTO_TEST_CASE( test_main ) +{ + using namespace boost::multiprecision; + expected_results(); + // + // Test at: + // 18 decimal digits: tests 80-bit long double approximations + // 30 decimal digits: tests 128-bit long double approximations + // 35 decimal digits: tests arbitrary precision code + // + ALL_TESTS +} + + + diff --git a/test/math/test_digamma.cpp b/test/math/test_digamma.cpp index e3a1bd56..b6b3afe5 100644 --- a/test/math/test_digamma.cpp +++ b/test/math/test_digamma.cpp @@ -30,6 +30,13 @@ void expected_results() ".*", // test type(s) ".*Negative.*", // test data group ".*", 350, 40); // test function + add_expected_result( + ".*", // compiler + ".*", // stdlib + ".*", // platform + ".*cpp_dec_float.*", // test type(s) + ".*Near the Positive Root.*", // test data group + ".*", 2500, 200); // test function add_expected_result( ".*", // compiler ".*", // stdlib diff --git a/test/math/test_ellint_3.cpp b/test/math/test_ellint_3.cpp index 21e12bd5..e7ef10d4 100644 --- a/test/math/test_ellint_3.cpp +++ b/test/math/test_ellint_3.cpp @@ -37,6 +37,13 @@ void expected_results() ".*", // test type(s) ".*Large.*", // test data group ".*", 75, 40); // test function + add_expected_result( + ".*", // compiler + ".*", // stdlib + ".*", // platform + ".*cpp_bin_float_quad.*", // test type(s) + ".*Mathworld.*", // test data group + ".*", 500, 100); // test function #ifdef BOOST_INTEL add_expected_result( ".*", // compiler From e6fd333f3c4b8a2c4d6f0cc288b4eab624eea7c0 Mon Sep 17 00:00:00 2001 From: Alexandre Hamez Date: Tue, 9 Jun 2015 13:54:59 +0200 Subject: [PATCH 29/33] Fix exception message --- include/boost/multiprecision/rational_adaptor.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/multiprecision/rational_adaptor.hpp b/include/boost/multiprecision/rational_adaptor.hpp index 3e294aab..16fd940a 100644 --- a/include/boost/multiprecision/rational_adaptor.hpp +++ b/include/boost/multiprecision/rational_adaptor.hpp @@ -134,7 +134,7 @@ struct rational_adaptor v2 = 1; if(*s) { - BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Could parse the string \"") + p + std::string("\" as a valid rational number."))); + BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Could not parse the string \"") + p + std::string("\" as a valid rational number."))); } data().assign(v1, v2); return *this; From 44d74a5ce1ab917b94a5d712284850f78e696023 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Tue, 16 Jun 2015 18:40:59 +0100 Subject: [PATCH 30/33] Fix definitions of numeric_limits out-of-line members. --- include/boost/multiprecision/float128.hpp | 46 +++++++++++------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/include/boost/multiprecision/float128.hpp b/include/boost/multiprecision/float128.hpp index cda8e824..cd70fa00 100644 --- a/include/boost/multiprecision/float128.hpp +++ b/include/boost/multiprecision/float128.hpp @@ -564,57 +564,57 @@ public: }; template -const bool numeric_limits >::is_specialized; +BOOST_CONSTEXPR_OR_CONST bool numeric_limits >::is_specialized; template -const int numeric_limits >::digits; +BOOST_CONSTEXPR_OR_CONST int numeric_limits >::digits; template -const int numeric_limits >::digits10; +BOOST_CONSTEXPR_OR_CONST int numeric_limits >::digits10; template -const int numeric_limits >::max_digits10; +BOOST_CONSTEXPR_OR_CONST int numeric_limits >::max_digits10; template -const bool numeric_limits >::is_signed; +BOOST_CONSTEXPR_OR_CONST bool numeric_limits >::is_signed; template -const bool numeric_limits >::is_integer; +BOOST_CONSTEXPR_OR_CONST bool numeric_limits >::is_integer; template -const bool numeric_limits >::is_exact; +BOOST_CONSTEXPR_OR_CONST bool numeric_limits >::is_exact; template -const int numeric_limits >::radix; +BOOST_CONSTEXPR_OR_CONST int numeric_limits >::radix; template -const int numeric_limits >::min_exponent; +BOOST_CONSTEXPR_OR_CONST int numeric_limits >::min_exponent; template -const int numeric_limits >::max_exponent; +BOOST_CONSTEXPR_OR_CONST int numeric_limits >::max_exponent; template -const int numeric_limits >::min_exponent10; +BOOST_CONSTEXPR_OR_CONST int numeric_limits >::min_exponent10; template -const int numeric_limits >::max_exponent10; +BOOST_CONSTEXPR_OR_CONST int numeric_limits >::max_exponent10; template -const bool numeric_limits >::has_infinity; +BOOST_CONSTEXPR_OR_CONST bool numeric_limits >::has_infinity; template -const bool numeric_limits >::has_quiet_NaN; +BOOST_CONSTEXPR_OR_CONST bool numeric_limits >::has_quiet_NaN; template -const bool numeric_limits >::has_signaling_NaN; +BOOST_CONSTEXPR_OR_CONST bool numeric_limits >::has_signaling_NaN; template -const bool numeric_limits >::has_denorm_loss; +BOOST_CONSTEXPR_OR_CONST bool numeric_limits >::has_denorm_loss; template -const bool numeric_limits >::is_iec559; +BOOST_CONSTEXPR_OR_CONST bool numeric_limits >::is_iec559; template -const bool numeric_limits >::is_bounded; +BOOST_CONSTEXPR_OR_CONST bool numeric_limits >::is_bounded; template -const bool numeric_limits >::is_modulo; +BOOST_CONSTEXPR_OR_CONST bool numeric_limits >::is_modulo; template -const bool numeric_limits >::traps; +BOOST_CONSTEXPR_OR_CONST bool numeric_limits >::traps; template -const bool numeric_limits >::tinyness_before; +BOOST_CONSTEXPR_OR_CONST bool numeric_limits >::tinyness_before; template -const float_round_style numeric_limits >::round_style; +BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits >::round_style; template -const float_denorm_style numeric_limits >::has_denorm; +BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits >::has_denorm; } // namespace std From 70198c3a67e4617742d009ceb373c027d05d8110 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Thu, 18 Jun 2015 09:08:52 +0100 Subject: [PATCH 31/33] Don't use conditional noexcept with gcc-4.6.x as it causes issues. See https://svn.boost.org/trac/boost/ticket/11402 --- .../boost/multiprecision/cpp_bin_float.hpp | 6 +- .../boost/multiprecision/cpp_dec_float.hpp | 6 +- include/boost/multiprecision/cpp_int.hpp | 58 +++++++++---------- include/boost/multiprecision/cpp_int/add.hpp | 44 +++++++------- .../boost/multiprecision/cpp_int/bitwise.hpp | 38 ++++++------ include/boost/multiprecision/cpp_int/misc.hpp | 14 ++--- .../boost/multiprecision/cpp_int/multiply.hpp | 28 ++++----- .../multiprecision/detail/number_base.hpp | 6 ++ include/boost/multiprecision/number.hpp | 34 +++++------ .../boost/multiprecision/rational_adaptor.hpp | 12 ++-- 10 files changed, 126 insertions(+), 120 deletions(-) diff --git a/include/boost/multiprecision/cpp_bin_float.hpp b/include/boost/multiprecision/cpp_bin_float.hpp index ec37bd38..4c007998 100644 --- a/include/boost/multiprecision/cpp_bin_float.hpp +++ b/include/boost/multiprecision/cpp_bin_float.hpp @@ -67,9 +67,9 @@ private: exponent_type m_exponent; bool m_sign; public: - cpp_bin_float() BOOST_NOEXCEPT_IF(noexcept(rep_type())) : m_data(), m_exponent(exponent_nan), m_sign(false) {} + cpp_bin_float() BOOST_MP_NOEXCEPT_IF(noexcept(rep_type())) : m_data(), m_exponent(exponent_nan), m_sign(false) {} - cpp_bin_float(const cpp_bin_float &o) BOOST_NOEXCEPT_IF(noexcept(rep_type(std::declval()))) + cpp_bin_float(const cpp_bin_float &o) BOOST_MP_NOEXCEPT_IF(noexcept(rep_type(std::declval()))) : m_data(o.m_data), m_exponent(o.m_exponent), m_sign(o.m_sign) {} template @@ -104,7 +104,7 @@ public: this->assign_float(f); } - cpp_bin_float& operator=(const cpp_bin_float &o) BOOST_NOEXCEPT_IF(noexcept(std::declval() = std::declval())) + cpp_bin_float& operator=(const cpp_bin_float &o) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval() = std::declval())) { m_data = o.m_data; m_exponent = o.m_exponent; diff --git a/include/boost/multiprecision/cpp_dec_float.hpp b/include/boost/multiprecision/cpp_dec_float.hpp index 0dd0a40e..737f9250 100644 --- a/include/boost/multiprecision/cpp_dec_float.hpp +++ b/include/boost/multiprecision/cpp_dec_float.hpp @@ -170,7 +170,7 @@ private: public: // Constructors - cpp_dec_float() BOOST_NOEXCEPT_IF(noexcept(array_type())) : + cpp_dec_float() BOOST_MP_NOEXCEPT_IF(noexcept(array_type())) : data(), exp (static_cast(0)), neg (false), @@ -215,7 +215,7 @@ public: from_unsigned_long_long(i); } - cpp_dec_float(const cpp_dec_float& f) BOOST_NOEXCEPT_IF(noexcept(array_type(std::declval()))) : + cpp_dec_float(const cpp_dec_float& f) BOOST_MP_NOEXCEPT_IF(noexcept(array_type(std::declval()))) : data (f.data), exp (f.exp), neg (f.neg), @@ -379,7 +379,7 @@ public: } // Basic operations. - cpp_dec_float& operator=(const cpp_dec_float& v) BOOST_NOEXCEPT_IF(noexcept(std::declval() = std::declval())) + cpp_dec_float& operator=(const cpp_dec_float& v) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval() = std::declval())) { data = v.data; exp = v.exp; diff --git a/include/boost/multiprecision/cpp_int.hpp b/include/boost/multiprecision/cpp_int.hpp index 0a4cc46c..d451567b 100644 --- a/include/boost/multiprecision/cpp_int.hpp +++ b/include/boost/multiprecision/cpp_int.hpp @@ -466,12 +466,12 @@ public: m_sign = false; } } - BOOST_MP_FORCEINLINE void resize(unsigned new_size, unsigned min_size) BOOST_NOEXCEPT_IF((Checked == unchecked)) + BOOST_MP_FORCEINLINE void resize(unsigned new_size, unsigned min_size) BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) { m_limbs = static_cast((std::min)(new_size, internal_limb_count)); detail::verify_new_size(m_limbs, min_size, checked_type()); } - BOOST_MP_FORCEINLINE void normalize() BOOST_NOEXCEPT_IF((Checked == unchecked)) + BOOST_MP_FORCEINLINE void normalize() BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) { limb_pointer p = limbs(); detail::verify_limb_mask(m_limbs == internal_limb_count, p[internal_limb_count-1], upper_limb_mask, checked_type()); @@ -581,12 +581,12 @@ public: // BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(limb_type i)BOOST_NOEXCEPT : m_wrapper(i), m_limbs(1) {} - BOOST_MP_FORCEINLINE cpp_int_base(signed_limb_type i)BOOST_NOEXCEPT_IF((Checked == unchecked)) + BOOST_MP_FORCEINLINE cpp_int_base(signed_limb_type i)BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) : m_wrapper(limb_type(i < 0 ? static_cast(-static_cast(i)) : i)), m_limbs(1) { if(i < 0) negate(); } #ifdef BOOST_LITTLE_ENDIAN BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(double_limb_type i)BOOST_NOEXCEPT : m_wrapper(i), m_limbs(i > max_limb_value ? 2 : 1) {} - BOOST_MP_FORCEINLINE cpp_int_base(signed_double_limb_type i)BOOST_NOEXCEPT_IF((Checked == unchecked)) + BOOST_MP_FORCEINLINE cpp_int_base(signed_double_limb_type i)BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) : m_wrapper(double_limb_type(i < 0 ? static_cast(boost::multiprecision::detail::unsigned_abs(i)) : i)), m_limbs(i < 0 ? (static_cast(boost::multiprecision::detail::unsigned_abs(i)) > max_limb_value ? 2 : 1) : (i > max_limb_value ? 2 : 1)) { @@ -607,13 +607,13 @@ public: BOOST_MP_FORCEINLINE limb_pointer limbs() BOOST_NOEXCEPT { return m_wrapper.m_data; } BOOST_MP_FORCEINLINE BOOST_CONSTEXPR const_limb_pointer limbs()const BOOST_NOEXCEPT { return m_wrapper.m_data; } BOOST_MP_FORCEINLINE BOOST_CONSTEXPR bool sign()const BOOST_NOEXCEPT { return false; } - BOOST_MP_FORCEINLINE void sign(bool b) BOOST_NOEXCEPT_IF((Checked == unchecked)) { if(b) negate(); } - BOOST_MP_FORCEINLINE void resize(unsigned new_size, unsigned min_size) BOOST_NOEXCEPT_IF((Checked == unchecked)) + BOOST_MP_FORCEINLINE void sign(bool b) BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) { if(b) negate(); } + BOOST_MP_FORCEINLINE void resize(unsigned new_size, unsigned min_size) BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) { m_limbs = (std::min)(new_size, internal_limb_count); detail::verify_new_size(m_limbs, min_size, checked_type()); } - BOOST_MP_FORCEINLINE void normalize() BOOST_NOEXCEPT_IF((Checked == unchecked)) + BOOST_MP_FORCEINLINE void normalize() BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) { limb_pointer p = limbs(); detail::verify_limb_mask(m_limbs == internal_limb_count, p[internal_limb_count-1], upper_limb_mask, checked_type()); @@ -643,7 +643,7 @@ private: } void check_negate(const mpl::int_&){} public: - void negate() BOOST_NOEXCEPT_IF((Checked == unchecked)) + void negate() BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) { // Not so much a negate as a complement - this gets called when subtraction // would result in a "negative" number: @@ -750,7 +750,7 @@ protected: void check_in_range(T, const mpl::int_&) BOOST_NOEXCEPT {} template - void check_in_range(T val) BOOST_NOEXCEPT_IF(noexcept(std::declval().check_in_range(std::declval(), checked_type()))) + void check_in_range(T val) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval().check_in_range(std::declval(), checked_type()))) { check_in_range(val, checked_type()); } @@ -760,17 +760,17 @@ public: // Direct construction: // template - BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(SI i, typename boost::enable_if_c::value && (Checked == unchecked) >::type const* = 0) BOOST_NOEXCEPT_IF(noexcept(std::declval().check_in_range(std::declval()))) + BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(SI i, typename boost::enable_if_c::value && (Checked == unchecked) >::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval().check_in_range(std::declval()))) : m_data(i < 0 ? static_cast(static_cast::type>(boost::multiprecision::detail::unsigned_abs(i)) & limb_mask) : static_cast(i)& limb_mask), m_sign(i < 0) {} template - BOOST_MP_FORCEINLINE cpp_int_base(SI i, typename boost::enable_if_c::value && (Checked == checked) >::type const* = 0) BOOST_NOEXCEPT_IF(noexcept(std::declval().check_in_range(std::declval()))) + BOOST_MP_FORCEINLINE cpp_int_base(SI i, typename boost::enable_if_c::value && (Checked == checked) >::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval().check_in_range(std::declval()))) : m_data(i < 0 ? (static_cast(static_cast::type>(boost::multiprecision::detail::unsigned_abs(i)) & limb_mask)) : static_cast(i)& limb_mask), m_sign(i < 0) { check_in_range(i); } template BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(UI i, typename boost::enable_if_c::value && (Checked == unchecked)>::type const* = 0) BOOST_NOEXCEPT : m_data(static_cast(i) & limb_mask), m_sign(false) {} template - BOOST_MP_FORCEINLINE cpp_int_base(UI i, typename boost::enable_if_c::value && (Checked == checked)>::type const* = 0) BOOST_NOEXCEPT_IF(noexcept(std::declval().check_in_range(std::declval()))) + BOOST_MP_FORCEINLINE cpp_int_base(UI i, typename boost::enable_if_c::value && (Checked == checked)>::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval().check_in_range(std::declval()))) : m_data(static_cast(i) & limb_mask), m_sign(false) { check_in_range(i); } template BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(F i, typename boost::enable_if_c::value && (Checked == unchecked)>::type const* = 0) BOOST_NOEXCEPT @@ -810,7 +810,7 @@ public: { detail::verify_new_size(2, min_size, checked_type()); } - BOOST_MP_FORCEINLINE void normalize() BOOST_NOEXCEPT_IF((Checked == unchecked)) + BOOST_MP_FORCEINLINE void normalize() BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) { if(!m_data) m_sign = false; // zero is always unsigned @@ -893,7 +893,7 @@ protected: BOOST_MP_FORCEINLINE void check_in_range(T, const mpl::int_&, const boost::integral_constant&) BOOST_NOEXCEPT {} template - BOOST_MP_FORCEINLINE void check_in_range(T val) BOOST_NOEXCEPT_IF(noexcept(std::declval().check_in_range(std::declval(), checked_type(), is_signed()))) + BOOST_MP_FORCEINLINE void check_in_range(T val) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval().check_in_range(std::declval(), checked_type(), is_signed()))) { check_in_range(val, checked_type(), is_signed()); } @@ -906,16 +906,16 @@ public: BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(SI i, typename boost::enable_if_c::value && (Checked == unchecked) >::type const* = 0) BOOST_NOEXCEPT : m_data(i < 0 ? (1 + ~static_cast(-i)) & limb_mask : static_cast(i) & limb_mask) {} template - BOOST_MP_FORCEINLINE cpp_int_base(SI i, typename boost::enable_if_c::value && (Checked == checked) >::type const* = 0) BOOST_NOEXCEPT_IF(noexcept(std::declval().check_in_range(std::declval()))) + BOOST_MP_FORCEINLINE cpp_int_base(SI i, typename boost::enable_if_c::value && (Checked == checked) >::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval().check_in_range(std::declval()))) : m_data(i < 0 ? 1 + ~static_cast(-i) : static_cast(i)) { check_in_range(i); } template BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_base(UI i, typename boost::enable_if_c::value && (Checked == unchecked) >::type const* = 0) BOOST_NOEXCEPT : m_data(static_cast(i) & limb_mask) {} template - BOOST_MP_FORCEINLINE cpp_int_base(UI i, typename boost::enable_if_c::value && (Checked == checked) >::type const* = 0) BOOST_NOEXCEPT_IF(noexcept(std::declval().check_in_range(std::declval()))) + BOOST_MP_FORCEINLINE cpp_int_base(UI i, typename boost::enable_if_c::value && (Checked == checked) >::type const* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval().check_in_range(std::declval()))) : m_data(static_cast(i)) { check_in_range(i); } template - BOOST_MP_FORCEINLINE cpp_int_base(F i, typename boost::enable_if >::type const* = 0) BOOST_NOEXCEPT_IF((Checked == unchecked)) + BOOST_MP_FORCEINLINE cpp_int_base(F i, typename boost::enable_if >::type const* = 0) BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) : m_data(static_cast(std::fabs(i)) & limb_mask) { check_in_range(i); @@ -939,7 +939,7 @@ public: BOOST_MP_FORCEINLINE limb_pointer limbs() BOOST_NOEXCEPT { return &m_data; } BOOST_MP_FORCEINLINE BOOST_CONSTEXPR const_limb_pointer limbs()const BOOST_NOEXCEPT { return &m_data; } BOOST_MP_FORCEINLINE BOOST_CONSTEXPR bool sign()const BOOST_NOEXCEPT { return false; } - BOOST_MP_FORCEINLINE void sign(bool b) BOOST_NOEXCEPT_IF((Checked == unchecked)) + BOOST_MP_FORCEINLINE void sign(bool b) BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) { if(b) negate(); @@ -948,7 +948,7 @@ public: { detail::verify_new_size(2, min_size, checked_type()); } - BOOST_MP_FORCEINLINE void normalize() BOOST_NOEXCEPT_IF((Checked == unchecked)) + BOOST_MP_FORCEINLINE void normalize() BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) { detail::verify_limb_mask(true, m_data, limb_mask, checked_type()); m_data &= limb_mask; @@ -962,7 +962,7 @@ public: { m_data = o.m_data; } - BOOST_MP_FORCEINLINE void negate() BOOST_NOEXCEPT_IF((Checked == unchecked)) + BOOST_MP_FORCEINLINE void negate() BOOST_MP_NOEXCEPT_IF((Checked == unchecked)) { if(Checked == checked) { @@ -1042,7 +1042,7 @@ public: typedef mpl::int_ checked_type; BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend() BOOST_NOEXCEPT{} - BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(const cpp_int_backend& o) BOOST_NOEXCEPT_IF(boost::is_void::value) : base_type(o) {} + BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF(boost::is_void::value) : base_type(o) {} #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(cpp_int_backend&& o) BOOST_NOEXCEPT : base_type(static_cast(o)) {} @@ -1051,7 +1051,7 @@ public: // Direct construction from arithmetic type: // template - BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(Arg i, typename boost::enable_if_c::value >::type const* = 0)BOOST_NOEXCEPT_IF(noexcept(base_type(std::declval()))) + BOOST_MP_FORCEINLINE BOOST_CONSTEXPR cpp_int_backend(Arg i, typename boost::enable_if_c::value >::type const* = 0)BOOST_MP_NOEXCEPT_IF(noexcept(base_type(std::declval()))) : base_type(i) {} private: @@ -1140,13 +1140,13 @@ public: : base_type(static_cast(a), tag){} #endif - BOOST_MP_FORCEINLINE cpp_int_backend& operator = (const cpp_int_backend& o) BOOST_NOEXCEPT_IF(noexcept(std::declval().assign(std::declval()))) + BOOST_MP_FORCEINLINE cpp_int_backend& operator = (const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval().assign(std::declval()))) { this->assign(o); return *this; } #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - BOOST_MP_FORCEINLINE cpp_int_backend& operator = (cpp_int_backend&& o) BOOST_NOEXCEPT_IF(noexcept(std::declval() = std::declval())) + BOOST_MP_FORCEINLINE cpp_int_backend& operator = (cpp_int_backend&& o) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval() = std::declval())) { *static_cast(this) = static_cast(o); return *this; @@ -1155,7 +1155,7 @@ public: private: template typename boost::enable_if >::type do_assign_arithmetic(A val, const mpl::true_&) - BOOST_NOEXCEPT_IF(noexcept(std::declval().check_in_range(std::declval()))) + BOOST_MP_NOEXCEPT_IF(noexcept(std::declval().check_in_range(std::declval()))) { this->check_in_range(val); *this->limbs() = static_cast(val); @@ -1163,7 +1163,7 @@ private: } template typename boost::disable_if_c::value || !is_integral::value >::type do_assign_arithmetic(A val, const mpl::true_&) - BOOST_NOEXCEPT_IF(noexcept(std::declval().check_in_range(std::declval())) && noexcept(std::declval().sign(true))) + BOOST_MP_NOEXCEPT_IF(noexcept(std::declval().check_in_range(std::declval())) && noexcept(std::declval().sign(true))) { this->check_in_range(val); *this->limbs() = (val < 0) ? static_cast(boost::multiprecision::detail::unsigned_abs(val)) : static_cast(val); @@ -1184,7 +1184,7 @@ private: *this->limbs() = i; this->sign(false); } - BOOST_MP_FORCEINLINE void do_assign_arithmetic(signed_limb_type i, const mpl::false_&) BOOST_NOEXCEPT_IF(noexcept(std::declval().sign(true))) + BOOST_MP_FORCEINLINE void do_assign_arithmetic(signed_limb_type i, const mpl::false_&) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval().sign(true))) { this->resize(1, 1); *this->limbs() = static_cast(boost::multiprecision::detail::unsigned_abs(i)); @@ -1200,7 +1200,7 @@ private: this->resize(p[1] ? 2 : 1, p[1] ? 2 : 1); this->sign(false); } - void do_assign_arithmetic(signed_double_limb_type i, const mpl::false_&) BOOST_NOEXCEPT_IF(noexcept(std::declval().sign(true))) + void do_assign_arithmetic(signed_double_limb_type i, const mpl::false_&) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval().sign(true))) { BOOST_STATIC_ASSERT(sizeof(i) == 2 * sizeof(limb_type)); BOOST_STATIC_ASSERT(base_type::internal_limb_count >= 2); @@ -1270,7 +1270,7 @@ private: } public: template - BOOST_MP_FORCEINLINE cpp_int_backend& operator = (Arithmetic val) BOOST_NOEXCEPT_IF(noexcept(std::declval().do_assign_arithmetic(std::declval(), trivial_tag()))) + BOOST_MP_FORCEINLINE cpp_int_backend& operator = (Arithmetic val) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval().do_assign_arithmetic(std::declval(), trivial_tag()))) { do_assign_arithmetic(val, trivial_tag()); return *this; diff --git a/include/boost/multiprecision/cpp_int/add.hpp b/include/boost/multiprecision/cpp_int/add.hpp index f9c9b85e..372998d6 100644 --- a/include/boost/multiprecision/cpp_int/add.hpp +++ b/include/boost/multiprecision/cpp_int/add.hpp @@ -14,7 +14,7 @@ namespace boost{ namespace multiprecision{ namespace backends{ // This is the key addition routine where all the argument types are non-trivial cpp_int's: // template -inline void add_unsigned(CppInt1& result, const CppInt2& a, const CppInt3& b) BOOST_NOEXCEPT_IF(is_non_throwing_cpp_int::value) +inline void add_unsigned(CppInt1& result, const CppInt2& a, const CppInt3& b) BOOST_MP_NOEXCEPT_IF(is_non_throwing_cpp_int::value) { using std::swap; @@ -81,7 +81,7 @@ inline void add_unsigned(CppInt1& result, const CppInt2& a, const CppInt3& b) BO // As above, but for adding a single limb to a non-trivial cpp_int: // template -inline void add_unsigned(CppInt1& result, const CppInt2& a, const limb_type& o) BOOST_NOEXCEPT_IF(is_non_throwing_cpp_int::value) +inline void add_unsigned(CppInt1& result, const CppInt2& a, const limb_type& o) BOOST_MP_NOEXCEPT_IF(is_non_throwing_cpp_int::value) { // Addition using modular arithmetic. // Nothing fancy, just let uintmax_t take the strain: @@ -119,7 +119,7 @@ inline void add_unsigned(CppInt1& result, const CppInt2& a, const limb_type& o) // Core subtraction routine for all non-trivial cpp_int's: // template -inline void subtract_unsigned(CppInt1& result, const CppInt2& a, const CppInt3& b) BOOST_NOEXCEPT_IF(is_non_throwing_cpp_int::value) +inline void subtract_unsigned(CppInt1& result, const CppInt2& a, const CppInt3& b) BOOST_MP_NOEXCEPT_IF(is_non_throwing_cpp_int::value) { using std::swap; @@ -203,7 +203,7 @@ inline void subtract_unsigned(CppInt1& result, const CppInt2& a, const CppInt3& // And again to subtract a single limb: // template -inline void subtract_unsigned(CppInt1& result, const CppInt2& a, const limb_type& b) BOOST_NOEXCEPT_IF(is_non_throwing_cpp_int::value) +inline void subtract_unsigned(CppInt1& result, const CppInt2& a, const limb_type& b) BOOST_MP_NOEXCEPT_IF(is_non_throwing_cpp_int::value) { // Subtract one limb. // Nothing fancy, just let uintmax_t take the strain: @@ -264,7 +264,7 @@ template >::value && !is_trivial_cpp_int >::value >::type eval_add( cpp_int_backend& result, - const cpp_int_backend& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { eval_add(result, result, o); } @@ -273,7 +273,7 @@ inline typename enable_if_c& result, const cpp_int_backend& a, - const cpp_int_backend& b) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& b) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { if(a.sign() != b.sign()) { @@ -284,7 +284,7 @@ inline typename enable_if_c BOOST_MP_FORCEINLINE typename enable_if_c >::value>::type - eval_add(cpp_int_backend& result, const limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + eval_add(cpp_int_backend& result, const limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { if(result.sign()) { @@ -298,7 +298,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c& result, const cpp_int_backend& a, - const limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { if(a.sign()) { @@ -311,7 +311,7 @@ template >::value>::type eval_add( cpp_int_backend& result, - const signed_limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const signed_limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { if(o < 0) eval_subtract(result, static_cast(boost::multiprecision::detail::unsigned_abs(o))); @@ -323,7 +323,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c& result, const cpp_int_backend& a, - const signed_limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const signed_limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { if(o < 0) eval_subtract(result, a, static_cast(boost::multiprecision::detail::unsigned_abs(o))); @@ -336,7 +336,7 @@ template >::value>::type eval_subtract( cpp_int_backend& result, - const limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { if(result.sign()) { @@ -350,7 +350,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c& result, const cpp_int_backend& a, - const limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { if(a.sign()) { @@ -365,7 +365,7 @@ template >::value>::type eval_subtract( cpp_int_backend& result, - const signed_limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const signed_limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { if(o) { @@ -380,7 +380,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c& result, const cpp_int_backend& a, - const signed_limb_type& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const signed_limb_type& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { if(o) { @@ -395,7 +395,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c BOOST_MP_FORCEINLINE typename enable_if_c >::value>::type - eval_increment(cpp_int_backend& result) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + eval_increment(cpp_int_backend& result) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { static const limb_type one = 1; if(!result.sign() && (result.limbs()[0] < cpp_int_backend::max_limb_value)) @@ -407,7 +407,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c BOOST_MP_FORCEINLINE typename enable_if_c >::value>::type - eval_decrement(cpp_int_backend& result) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + eval_decrement(cpp_int_backend& result) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { static const limb_type one = 1; if(!result.sign() && result.limbs()[0]) @@ -421,7 +421,7 @@ template >::value && !is_trivial_cpp_int >::value >::type eval_subtract( cpp_int_backend& result, - const cpp_int_backend& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { eval_subtract(result, result, o); } @@ -430,7 +430,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c& result, const cpp_int_backend& a, - const cpp_int_backend& b) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& b) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { if(a.sign() != b.sign()) { @@ -453,7 +453,7 @@ inline typename enable_if_c< >::type eval_add( cpp_int_backend& result, - const cpp_int_backend& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { if(result.sign() != o.sign()) { @@ -478,7 +478,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c< && is_unsigned_number >::value >::type eval_add(cpp_int_backend& result, - const cpp_int_backend& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { *result.limbs() = detail::checked_add(*result.limbs(), *o.limbs(), typename cpp_int_backend::checked_type()); result.normalize(); @@ -493,7 +493,7 @@ inline typename enable_if_c< >::type eval_subtract( cpp_int_backend& result, - const cpp_int_backend& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { if(result.sign() != o.sign()) { @@ -518,7 +518,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c< >::type eval_subtract( cpp_int_backend& result, - const cpp_int_backend& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { *result.limbs() = detail::checked_subtract(*result.limbs(), *o.limbs(), typename cpp_int_backend::checked_type()); result.normalize(); diff --git a/include/boost/multiprecision/cpp_int/bitwise.hpp b/include/boost/multiprecision/cpp_int/bitwise.hpp index 63d3b639..a39e2590 100644 --- a/include/boost/multiprecision/cpp_int/bitwise.hpp +++ b/include/boost/multiprecision/cpp_int/bitwise.hpp @@ -44,7 +44,7 @@ template void bitwise_op( CppInt1& result, const CppInt2& o, - Op op, const mpl::true_&) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int::value)) + Op op, const mpl::true_&) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int::value)) { // // There are 4 cases: @@ -184,7 +184,7 @@ template void bitwise_op( CppInt1& result, const CppInt2& o, - Op op, const mpl::false_&) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int::value)) + Op op, const mpl::false_&) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int::value)) { // // Both arguments are unsigned types, very simple case handled as a special case. @@ -217,7 +217,7 @@ template >::value && !is_trivial_cpp_int >::value >::type eval_bitwise_and( cpp_int_backend& result, - const cpp_int_backend& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { bitwise_op(result, o, bit_and(), mpl::bool_ > >::is_signed || std::numeric_limits > >::is_signed>()); @@ -227,7 +227,7 @@ template >::value && !is_trivial_cpp_int >::value >::type eval_bitwise_or( cpp_int_backend& result, - const cpp_int_backend& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { bitwise_op(result, o, bit_or(), mpl::bool_ > >::is_signed || std::numeric_limits > >::is_signed>()); @@ -237,7 +237,7 @@ template >::value && !is_trivial_cpp_int >::value >::type eval_bitwise_xor( cpp_int_backend& result, - const cpp_int_backend& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { bitwise_op(result, o, bit_xor(), mpl::bool_ > >::is_signed || std::numeric_limits > >::is_signed>()); @@ -277,7 +277,7 @@ template >::value && !is_trivial_cpp_int >::value && !is_trivial_cpp_int >::value >::type eval_complement( cpp_int_backend& result, - const cpp_int_backend& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { BOOST_STATIC_ASSERT_MSG(((Checked1 != checked) || (Checked2 != checked)), "Attempt to take the complement of a signed type results in undefined behavior."); // Increment and negate: @@ -290,7 +290,7 @@ template >::value && !is_trivial_cpp_int >::value && !is_trivial_cpp_int >::value >::type eval_complement( cpp_int_backend& result, - const cpp_int_backend& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { unsigned os = o.size(); result.resize(UINT_MAX, os); @@ -305,7 +305,7 @@ template >::value>::type eval_left_shift( cpp_int_backend& result, - double_limb_type s) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + double_limb_type s) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { is_valid_bitwise_op(result, typename cpp_int_backend::checked_type()); if(!s) @@ -382,7 +382,7 @@ template >::value>::type eval_right_shift( cpp_int_backend& result, - double_limb_type s) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + double_limb_type s) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { is_valid_bitwise_op(result, typename cpp_int_backend::checked_type()); if(!s) @@ -442,7 +442,7 @@ inline typename enable_if_c BOOST_MP_FORCEINLINE typename enable_if > >::type - eval_left_shift(cpp_int_backend& result, T s) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + eval_left_shift(cpp_int_backend& result, T s) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { is_valid_bitwise_op(result, typename cpp_int_backend::checked_type()); *result.limbs() = detail::checked_left_shift(*result.limbs(), s, typename cpp_int_backend::checked_type()); @@ -451,7 +451,7 @@ BOOST_MP_FORCEINLINE typename enable_if BOOST_MP_FORCEINLINE typename enable_if > >::type - eval_right_shift(cpp_int_backend& result, T s) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + eval_right_shift(cpp_int_backend& result, T s) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { // Nothing to check here... just make sure we don't invoke undefined behavior: is_valid_bitwise_op(result, typename cpp_int_backend::checked_type()); @@ -466,7 +466,7 @@ inline typename enable_if_c< >::type eval_bitwise_and( cpp_int_backend& result, - const cpp_int_backend& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { is_valid_bitwise_op(result, o, typename cpp_int_backend::checked_type()); @@ -503,7 +503,7 @@ inline typename enable_if_c< >::type eval_bitwise_and( cpp_int_backend& result, - const cpp_int_backend& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { *result.limbs() &= *o.limbs(); } @@ -516,7 +516,7 @@ inline typename enable_if_c< >::type eval_bitwise_or( cpp_int_backend& result, - const cpp_int_backend& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { is_valid_bitwise_op(result, o, typename cpp_int_backend::checked_type()); @@ -554,7 +554,7 @@ inline typename enable_if_c< >::type eval_bitwise_or( cpp_int_backend& result, - const cpp_int_backend& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { *result.limbs() |= *o.limbs(); } @@ -567,7 +567,7 @@ inline typename enable_if_c< >::type eval_bitwise_xor( cpp_int_backend& result, - const cpp_int_backend& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { is_valid_bitwise_op(result, o, typename cpp_int_backend::checked_type()); @@ -604,7 +604,7 @@ inline typename enable_if_c< >::type eval_bitwise_xor( cpp_int_backend& result, - const cpp_int_backend& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { *result.limbs() ^= *o.limbs(); } @@ -617,7 +617,7 @@ inline typename enable_if_c< >::type eval_complement( cpp_int_backend& result, - const cpp_int_backend& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { BOOST_STATIC_ASSERT_MSG(((Checked1 != checked) || (Checked2 != checked)), "Attempt to take the complement of a signed type results in undefined behavior."); // @@ -645,7 +645,7 @@ inline typename enable_if_c< >::type eval_complement( cpp_int_backend& result, - const cpp_int_backend& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { *result.limbs() = ~*o.limbs(); result.normalize(); diff --git a/include/boost/multiprecision/cpp_int/misc.hpp b/include/boost/multiprecision/cpp_int/misc.hpp index 266edac2..a124710c 100644 --- a/include/boost/multiprecision/cpp_int/misc.hpp +++ b/include/boost/multiprecision/cpp_int/misc.hpp @@ -55,7 +55,7 @@ inline Integer negate_integer(Integer i, const mpl::false_&) BOOST_NOEXCEPT template inline typename enable_if_c::value && !is_trivial_cpp_int >::value, void>::type - eval_convert_to(R* result, const cpp_int_backend& backend) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + eval_convert_to(R* result, const cpp_int_backend& backend) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { typedef mpl::int_ checked_type; check_in_range(backend, checked_type()); @@ -76,7 +76,7 @@ inline typename enable_if_c::value && !is_trivial_cpp_int inline typename enable_if_c::value && !is_trivial_cpp_int >::value, void>::type - eval_convert_to(R* result, const cpp_int_backend& backend) BOOST_NOEXCEPT_IF(is_arithmetic::value) + eval_convert_to(R* result, const cpp_int_backend& backend) BOOST_MP_NOEXCEPT_IF(is_arithmetic::value) { typename cpp_int_backend::const_limb_pointer p = backend.limbs(); unsigned shift = cpp_int_backend::limb_bits; @@ -104,7 +104,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c BOOST_MP_FORCEINLINE typename enable_if_c >::value>::type - eval_abs(cpp_int_backend& result, const cpp_int_backend& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + eval_abs(cpp_int_backend& result, const cpp_int_backend& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { result = val; result.sign(false); @@ -234,7 +234,7 @@ inline typename enable_if_c& x, const cpp_int_backend& y, cpp_int_backend& q, - cpp_int_backend& r) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + cpp_int_backend& r) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { divide_unsigned_helper(&q, x, y, r); q.sign(x.sign() != y.sign()); @@ -247,7 +247,7 @@ inline typename enable_if_c& x, limb_type y, cpp_int_backend& q, - cpp_int_backend& r) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + cpp_int_backend& r) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { divide_unsigned_helper(&q, x, y, r); q.sign(x.sign()); @@ -259,7 +259,7 @@ inline typename enable_if_c::value>::type eval_qr( const cpp_int_backend& x, U y, cpp_int_backend& q, - cpp_int_backend& r) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + cpp_int_backend& r) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { using default_ops::eval_qr; cpp_int_backend t(y); @@ -511,7 +511,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c BOOST_MP_FORCEINLINE typename enable_if_c >::value && (Checked1 == unchecked)>::type - eval_lcm(cpp_int_backend& result, const cpp_int_backend& a, const cpp_int_backend& b) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + eval_lcm(cpp_int_backend& result, const cpp_int_backend& a, const cpp_int_backend& b) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { *result.limbs() = boost::integer::lcm(*a.limbs(), *b.limbs()); result.normalize(); // result may overflow the specified number of bits diff --git a/include/boost/multiprecision/cpp_int/multiply.hpp b/include/boost/multiprecision/cpp_int/multiply.hpp index dbd8e29a..226bc9d1 100644 --- a/include/boost/multiprecision/cpp_int/multiply.hpp +++ b/include/boost/multiprecision/cpp_int/multiply.hpp @@ -15,7 +15,7 @@ inline typename enable_if_c& result, const cpp_int_backend& a, - const limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { if(!val) { @@ -67,7 +67,7 @@ inline typename enable_if_c& result, const cpp_int_backend& a, - const cpp_int_backend& b) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& b) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { // Very simple long multiplication, only usable for small numbers of limb_type's // but that's the typical use case for this type anyway: @@ -159,14 +159,14 @@ template >::value && !is_trivial_cpp_int >::value >::type eval_multiply( cpp_int_backend& result, - const cpp_int_backend& a) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& a) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { eval_multiply(result, result, a); } template BOOST_MP_FORCEINLINE typename enable_if_c >::value>::type - eval_multiply(cpp_int_backend& result, const limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + eval_multiply(cpp_int_backend& result, const limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { eval_multiply(result, result, val); } @@ -176,7 +176,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c& result, const cpp_int_backend& a, - const double_limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const double_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { if(val <= (std::numeric_limits::max)()) { @@ -191,7 +191,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c BOOST_MP_FORCEINLINE typename enable_if_c >::value>::type - eval_multiply(cpp_int_backend& result, const double_limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + eval_multiply(cpp_int_backend& result, const double_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { eval_multiply(result, result, val); } @@ -201,7 +201,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c& result, const cpp_int_backend& a, - const signed_limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const signed_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { if(val > 0) eval_multiply(result, a, static_cast(val)); @@ -214,7 +214,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c BOOST_MP_FORCEINLINE typename enable_if_c >::value>::type - eval_multiply(cpp_int_backend& result, const signed_limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + eval_multiply(cpp_int_backend& result, const signed_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { eval_multiply(result, result, val); } @@ -224,7 +224,7 @@ inline typename enable_if_c& result, const cpp_int_backend& a, - const signed_double_limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const signed_double_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { if(val > 0) { @@ -246,7 +246,7 @@ inline typename enable_if_c BOOST_MP_FORCEINLINE typename enable_if_c >::value>::type - eval_multiply(cpp_int_backend& result, const signed_double_limb_type& val) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + eval_multiply(cpp_int_backend& result, const signed_double_limb_type& val) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { eval_multiply(result, result, val); } @@ -263,7 +263,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c< >::type eval_multiply( cpp_int_backend& result, - const cpp_int_backend& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { *result.limbs() = detail::checked_multiply(*result.limbs(), *o.limbs(), typename cpp_int_backend::checked_type()); result.sign(result.sign() != o.sign()); @@ -277,7 +277,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c< >::type eval_multiply( cpp_int_backend& result, - const cpp_int_backend& o) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& o) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { *result.limbs() = detail::checked_multiply(*result.limbs(), *o.limbs(), typename cpp_int_backend::checked_type()); result.normalize(); @@ -293,7 +293,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c< eval_multiply( cpp_int_backend& result, const cpp_int_backend& a, - const cpp_int_backend& b) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& b) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { *result.limbs() = detail::checked_multiply(*a.limbs(), *b.limbs(), typename cpp_int_backend::checked_type()); result.sign(a.sign() != b.sign()); @@ -308,7 +308,7 @@ BOOST_MP_FORCEINLINE typename enable_if_c< eval_multiply( cpp_int_backend& result, const cpp_int_backend& a, - const cpp_int_backend& b) BOOST_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) + const cpp_int_backend& b) BOOST_MP_NOEXCEPT_IF((is_non_throwing_cpp_int >::value)) { *result.limbs() = detail::checked_multiply(*a.limbs(), *b.limbs(), typename cpp_int_backend::checked_type()); result.normalize(); diff --git a/include/boost/multiprecision/detail/number_base.hpp b/include/boost/multiprecision/detail/number_base.hpp index 4ff04edd..d7257790 100644 --- a/include/boost/multiprecision/detail/number_base.hpp +++ b/include/boost/multiprecision/detail/number_base.hpp @@ -25,6 +25,12 @@ # define BOOST_MP_FORCEINLINE inline #endif +#if defined(BOOST_GCC) && (BOOST_GCC <= 40700) +# define BOOST_MP_NOEXCEPT_IF(x) +#else +# define BOOST_MP_NOEXCEPT_IF(x) BOOST_NOEXCEPT_IF(x) +#endif + #ifdef BOOST_MSVC # pragma warning(push) # pragma warning(disable:6326) diff --git a/include/boost/multiprecision/number.hpp b/include/boost/multiprecision/number.hpp index 321457c3..92242847 100644 --- a/include/boost/multiprecision/number.hpp +++ b/include/boost/multiprecision/number.hpp @@ -40,8 +40,8 @@ class number typedef number self_type; public: typedef Backend backend_type; - BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number() BOOST_NOEXCEPT_IF(noexcept(Backend())) {} - BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number(const number& e) BOOST_NOEXCEPT_IF(noexcept(Backend(std::declval()))) : m_backend(e.m_backend){} + BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number() BOOST_MP_NOEXCEPT_IF(noexcept(Backend())) {} + BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number(const number& e) BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval()))) : m_backend(e.m_backend){} template BOOST_MP_FORCEINLINE number(const V& v, typename boost::enable_if_c< (boost::is_arithmetic::value || is_same::value || is_convertible::value) @@ -57,11 +57,11 @@ public: && !detail::is_restricted_conversion::type, Backend>::value >::type* = 0) #ifndef BOOST_INTEL - BOOST_NOEXCEPT_IF(noexcept(Backend(std::declval::type const&>()))) + BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval::type const&>()))) #endif : m_backend(canonical_value(v)) {} BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number(const number& e, unsigned digits10) - BOOST_NOEXCEPT_IF(noexcept(Backend(std::declval(), std::declval()))) + BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval(), std::declval()))) : m_backend(e.m_backend, digits10){} template explicit BOOST_MP_FORCEINLINE number(const V& v, typename boost::enable_if_c< @@ -69,7 +69,7 @@ public: && !detail::is_explicitly_convertible::type, Backend>::value && detail::is_restricted_conversion::type, Backend>::value >::type* = 0) - BOOST_NOEXCEPT_IF(noexcept(std::declval() = std::declval::type const&>())) + BOOST_MP_NOEXCEPT_IF(noexcept(std::declval() = std::declval::type const&>())) { m_backend = canonical_value(v); } @@ -79,7 +79,7 @@ public: && (detail::is_restricted_conversion::type, Backend>::value || !is_convertible::type, Backend>::value) >::type* = 0) - BOOST_NOEXCEPT_IF(noexcept(Backend(std::declval::type const&>()))) + BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval::type const&>()))) : m_backend(canonical_value(v)) {} /* // @@ -95,12 +95,12 @@ public: */ template BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number(const number& val) - BOOST_NOEXCEPT_IF(noexcept(Backend(std::declval()))) : m_backend(val.backend()) {} + BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval()))) : m_backend(val.backend()) {} template BOOST_MP_FORCEINLINE number(const number& val, typename boost::enable_if_c<(boost::is_convertible::value && !detail::is_restricted_conversion::value)>::type* = 0) - BOOST_NOEXCEPT_IF(noexcept(Backend(std::declval()))) + BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval()))) : m_backend(val.backend()) {} template @@ -117,7 +117,7 @@ public: explicit BOOST_MP_FORCEINLINE number(const number& val, typename boost::enable_if_c< (detail::is_explicitly_convertible::value && (detail::is_restricted_conversion::value || !boost::is_convertible::value)) - >::type* = 0) BOOST_NOEXCEPT_IF(noexcept(Backend(std::declval()))) + >::type* = 0) BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval()))) : m_backend(val.backend()) {} template @@ -149,7 +149,7 @@ public: } BOOST_MP_FORCEINLINE number& operator=(const number& e) - BOOST_NOEXCEPT_IF(noexcept(std::declval() = std::declval())) + BOOST_MP_NOEXCEPT_IF(noexcept(std::declval() = std::declval())) { m_backend = e.m_backend; return *this; @@ -158,14 +158,14 @@ public: template BOOST_MP_FORCEINLINE typename boost::enable_if, number& >::type operator=(const V& v) - BOOST_NOEXCEPT_IF(noexcept(std::declval() = std::declval::type&>())) + BOOST_MP_NOEXCEPT_IF(noexcept(std::declval() = std::declval::type&>())) { m_backend = canonical_value(v); return *this; } template BOOST_MP_FORCEINLINE number& assign(const V& v) - BOOST_NOEXCEPT_IF(noexcept(std::declval() = std::declval::type&>())) + BOOST_MP_NOEXCEPT_IF(noexcept(std::declval() = std::declval::type&>())) { m_backend = canonical_value(v); return *this; @@ -196,9 +196,9 @@ public: #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES BOOST_MP_FORCEINLINE BOOST_CONSTEXPR number(number&& r) - BOOST_NOEXCEPT_IF(noexcept(Backend(std::declval()))) + BOOST_MP_NOEXCEPT_IF(noexcept(Backend(std::declval()))) : m_backend(static_cast(r.m_backend)){} - BOOST_MP_FORCEINLINE number& operator=(number&& r) BOOST_NOEXCEPT_IF(noexcept(std::declval() = std::declval())) + BOOST_MP_FORCEINLINE number& operator=(number&& r) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval() = std::declval())) { m_backend = static_cast(r.m_backend); return *this; @@ -547,7 +547,7 @@ public: // // swap: // - BOOST_MP_FORCEINLINE void swap(self_type& other) BOOST_NOEXCEPT_IF(noexcept(std::declval().swap(std::declval()))) + BOOST_MP_FORCEINLINE void swap(self_type& other) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval().swap(std::declval()))) { m_backend.swap(other.backend()); } @@ -664,7 +664,7 @@ public: // Comparison: // BOOST_MP_FORCEINLINE int compare(const number& o)const - BOOST_NOEXCEPT_IF(noexcept(std::declval().compare(std::declval()))) + BOOST_MP_NOEXCEPT_IF(noexcept(std::declval().compare(std::declval()))) { return m_backend.compare(o.m_backend); } @@ -1726,7 +1726,7 @@ inline std::istream& operator >> (std::istream& is, number BOOST_MP_FORCEINLINE void swap(number& a, number& b) - BOOST_NOEXCEPT_IF(noexcept(std::declval&>() = std::declval&>())) + BOOST_MP_NOEXCEPT_IF(noexcept(std::declval&>() = std::declval&>())) { a.swap(b); } diff --git a/include/boost/multiprecision/rational_adaptor.hpp b/include/boost/multiprecision/rational_adaptor.hpp index 16fd940a..e3cec0e4 100644 --- a/include/boost/multiprecision/rational_adaptor.hpp +++ b/include/boost/multiprecision/rational_adaptor.hpp @@ -34,12 +34,12 @@ struct rational_adaptor typedef typename IntBackend::unsigned_types unsigned_types; typedef typename IntBackend::float_types float_types; - rational_adaptor() BOOST_NOEXCEPT_IF(noexcept(rational_type())) {} - rational_adaptor(const rational_adaptor& o) BOOST_NOEXCEPT_IF(noexcept(std::declval() = std::declval())) + rational_adaptor() BOOST_MP_NOEXCEPT_IF(noexcept(rational_type())) {} + rational_adaptor(const rational_adaptor& o) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval() = std::declval())) { m_value = o.m_value; } - rational_adaptor(const IntBackend& o) BOOST_NOEXCEPT_IF(noexcept(rational_type(std::declval()))) : m_value(o) {} + rational_adaptor(const IntBackend& o) BOOST_MP_NOEXCEPT_IF(noexcept(rational_type(std::declval()))) : m_value(o) {} template rational_adaptor(const U& u, typename enable_if_c::value>::type* = 0) @@ -57,9 +57,9 @@ struct rational_adaptor } #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - rational_adaptor(rational_adaptor&& o) BOOST_NOEXCEPT_IF(noexcept(rational_type(std::declval()))) : m_value(static_cast(o.m_value)) {} - rational_adaptor(IntBackend&& o) BOOST_NOEXCEPT_IF(noexcept(rational_type(std::declval()))) : m_value(static_cast(o)) {} - rational_adaptor& operator = (rational_adaptor&& o) BOOST_NOEXCEPT_IF(noexcept(std::declval() = std::declval())) + rational_adaptor(rational_adaptor&& o) BOOST_MP_NOEXCEPT_IF(noexcept(rational_type(std::declval()))) : m_value(static_cast(o.m_value)) {} + rational_adaptor(IntBackend&& o) BOOST_MP_NOEXCEPT_IF(noexcept(rational_type(std::declval()))) : m_value(static_cast(o)) {} + rational_adaptor& operator = (rational_adaptor&& o) BOOST_MP_NOEXCEPT_IF(noexcept(std::declval() = std::declval())) { m_value = static_cast(o.m_value); return *this; From d188b541f1f43bf93d3cbd907379e766f7fba4ed Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Thu, 18 Jun 2015 10:50:27 +0100 Subject: [PATCH 32/33] Update history. Conflicts: doc/html/boost_multiprecision/indexes/s01.html doc/html/boost_multiprecision/indexes/s02.html doc/html/boost_multiprecision/indexes/s03.html doc/html/boost_multiprecision/indexes/s04.html doc/html/boost_multiprecision/map/hist.html doc/html/index.html --- doc/multiprecision.qbk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/multiprecision.qbk b/doc/multiprecision.qbk index 58700f7b..c01560b6 100644 --- a/doc/multiprecision.qbk +++ b/doc/multiprecision.qbk @@ -4976,6 +4976,8 @@ Windows Vista machine. * Depricated boost/multiprecision/random.hpp as it's no longer needed, updated random examples to match. * Fixed a bug in cpp_int's right shift operator when shifting negative values - semantics now gives the same values as shifting 2's compliment integers, though not the same bit pattern. +* Fixed support for GCC-4.6.4 in C++0x mode by disabling conditional noexcept suppoprt for that compiler +see [@https://svn.boost.org/trac/boost/ticket/11402 #11402]. [h4 Multiprecision-2.2.4 (Boost-1.58)] From 4558e574d1d7bfd62550dac0b0b9b3e0ce9c3f38 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Mon, 20 Jul 2015 13:04:54 +0100 Subject: [PATCH 33/33] Bring docs into line with code, regenerate HTML. --- .../boost_multiprecision/indexes/s01.html | 2 +- .../boost_multiprecision/indexes/s02.html | 2 +- .../boost_multiprecision/indexes/s03.html | 9 +-- .../boost_multiprecision/indexes/s04.html | 17 +----- doc/html/boost_multiprecision/map/hist.html | 45 +++++++++++--- doc/html/index.html | 2 +- doc/multiprecision.qbk | 58 ++++++------------- 7 files changed, 58 insertions(+), 77 deletions(-) diff --git a/doc/html/boost_multiprecision/indexes/s01.html b/doc/html/boost_multiprecision/indexes/s01.html index 26bb2fd2..68be1403 100644 --- a/doc/html/boost_multiprecision/indexes/s01.html +++ b/doc/html/boost_multiprecision/indexes/s01.html @@ -24,7 +24,7 @@

-Function Index

+Function Index

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

diff --git a/doc/html/boost_multiprecision/indexes/s02.html b/doc/html/boost_multiprecision/indexes/s02.html index f8132613..44060266 100644 --- a/doc/html/boost_multiprecision/indexes/s02.html +++ b/doc/html/boost_multiprecision/indexes/s02.html @@ -24,7 +24,7 @@

-Class Index

+Class Index

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 048f054d..81d3604f 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

@@ -245,13 +245,6 @@

mpz_int

-
  • -

    mp_type

    - -
  • S diff --git a/doc/html/boost_multiprecision/indexes/s04.html b/doc/html/boost_multiprecision/indexes/s04.html index 4391d933..9ec6c3e5 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

    @@ -119,10 +119,6 @@
    • -

      Polynomial Evaluation

      - -
    • -
    • powm

      • Generic Integer Operations

      • diff --git a/doc/html/boost_multiprecision/map/hist.html b/doc/html/boost_multiprecision/map/hist.html index 047fbe93..6f2d72dc 100644 --- a/doc/html/boost_multiprecision/map/hist.html +++ b/doc/html/boost_multiprecision/map/hist.html @@ -28,6 +28,33 @@
    + Multiprecision-2.2.5 + (Boost-1.59) +
    +
      +
    • + Fixed a bug in cpp_int's right shift operator when shifting negative + values - semantics now gives the same values as shifting 2's compliment + integers, though not the same bit pattern. +
    • +
    • + Fixed support for GCC-4.6.4 in C++0x mode by disabling conditional noexcept + suppoprt for that compiler see #11402. +
    • +
    • + Fixed issue with GCC-4.6.x not handling noexcept + fully enough for this library to use. +
    • +
    • + Suppressed numerous compiler warnings. +
    • +
    • + Fixed some bugs in cpp_int's bitwise operators when one or both numbers + are signed. +
    • +
    +
    + Multiprecision-2.2.4 (Boost-1.58)
    @@ -48,7 +75,7 @@
    - + Multiprecision-2.2.3 (Boost-1.57)
    @@ -68,7 +95,7 @@
    - + Multiprecision-2.2.2 (Boost-1.56)
    @@ -81,14 +108,14 @@
    - + Multiprecision-2.2.1
    • Fix bug in assignment from string in cpp_int, see 9936.
    - + Multiprecision-2.2.0
      @@ -116,7 +143,7 @@
    - + Boost-1.55
      @@ -154,7 +181,7 @@
    - + 1.54
      @@ -209,7 +236,7 @@
    - + 1.53
      @@ -225,7 +252,7 @@
    - + Post review changes
    @@ -279,7 +306,7 @@
    - + Pre-review history
    diff --git a/doc/html/index.html b/doc/html/index.html index 7e9cc0d5..b2f978e8 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -163,7 +163,7 @@ - +

    Last revised: March 20, 2015 at 18:44:06 GMT

    Last revised: July 20, 2015 at 12:04:05 GMT


    diff --git a/doc/multiprecision.qbk b/doc/multiprecision.qbk index c01560b6..3373dce5 100644 --- a/doc/multiprecision.qbk +++ b/doc/multiprecision.qbk @@ -1607,60 +1607,33 @@ backends converting constructor is also explicit. [section:random Generating Random Numbers] -Random numbers are generated in conjunction with Boost.Random. +Random numbers are generated in conjunction with Boost.Random. However, since Boost.Random is unaware +of [@http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic arbitrary precision] numbers, it's necessary to include the header: -There is a single generator that supports generating random integers with large bit counts: -[@http://www.boost.org/doc/html/boost/random/independent_bits_engine.html `independent_bits_engine`]. -This type can be used with either ['unbounded] integer types, or with ['bounded] (ie fixed precision) unsigned integers: + #include + +In order to act as a bridge between the two libraries. + +Integers with /N/ random bits are generated using `independent_bits_engine`: [random_eg1] -Program output is: - -[random_eg1_out] - -In addition, the generator adaptors [@http://www.boost.org/doc/html/boost/random/discard_block_engine.html `discard_block`], -[@http://www.boost.org/doc/html/boost/random/xor_combine_engine.html `xor_combine_engine`] and -[@http://www.boost.org/doc/html/boost/random/discrete_distribution.html `discrete_distribution`] can be used -with multiprecision types. Note that if you seed an `independent_bits_engine`, then you are actually seeding -the underlying generator, and should therefore provide a sequence of unsigned 32-bit values as the seed. - -Alternatively we can generate integers in a given range using -[@http://www.boost.org/doc/html/boost/random/uniform_int_distribution.html `uniform_int_distribution`], this will +Alternatively we can generate integers in a given range using `uniform_int_distribution`, this will invoke the underlying engine multiple times to build up the required number of bits in the result: [random_eg2] -[random_eg2_out] - -It is also possible to use [@http://www.boost.org/doc/html/boost/random/uniform_int_distribution.html `uniform_int_distribution`] -with a multiprecision generator such as [@http://www.boost.org/doc/html/boost/random/independent_bits_engine.html `independent_bits_engine`]. -Or to use [@http://www.boost.org/doc/html/boost/random/uniform_smallint.html `uniform_smallint`] or -[@http://www.boost.org/doc/html/boost/random/random_number_generator.html `random_number_generator`] with multiprecision types. - -Floating point values in \[0,1) are most easily generated using [@http://www.boost.org/doc/html/boost/random/generate_canonical.html `generate_canonical`], -note that `generate_canonical` will call the generator multiple times to produce the requested number of bits, for example we can use -it with a regular generator like so: +Floating point values in \[0,1) are generated using `uniform_01`, the trick here is to ensure +that the underlying generator produces as many random bits as there are digits in the floating +point type. As above `independent_bits_engine` can be used for this purpose, note that we also have to +convert decimal digits (in the floating point type) to bits (in the random number generator): [random_eg3] -[random_eg3_out] - -Note however, the distributions do not invoke the generator multiple times to fill up the mantissa of a multiprecision floating point type -with random bits. For these therefore, we should probably use a multiprecision generator (ie `independent_bits_engine`) in combination -with the distribution: +Finally, we can modify the above example to produce numbers distributed according to some distribution: [random_eg4] -[random_eg4_out] - -And finally, it is possible to use the floating point generators [@http://www.boost.org/doc/html/boost/random/lagged_fibonacci_01_engine.html `lagged_fibonacci_01_engine`] -and [@http://www.boost.org/doc/html/boost/random/subtract_with_idp144360752.html `subtract_with_carry_01_engine`] directly with multiprecision floating point types. -It's worth noting however, that there is a distinct lack of literature on generating high bit-count random numbers, and therefore a lack of "known good" parameters to -use with these generators in this situation. For this reason, these should probably be used for research purposes only: - -[random_eg5] - [endsect] [section:primetest Primality Testing] @@ -4973,11 +4946,14 @@ Windows Vista machine. [h4 Multiprecision-2.2.5 (Boost-1.59)] -* Depricated boost/multiprecision/random.hpp as it's no longer needed, updated random examples to match. * Fixed a bug in cpp_int's right shift operator when shifting negative values - semantics now gives the same values as shifting 2's compliment integers, though not the same bit pattern. * Fixed support for GCC-4.6.4 in C++0x mode by disabling conditional noexcept suppoprt for that compiler see [@https://svn.boost.org/trac/boost/ticket/11402 #11402]. +* Fixed issue with GCC-4.6.x not handling `noexcept` fully enough for this library to use. +* Suppressed numerous compiler warnings. +* Fixed some bugs in cpp_int's bitwise operators when one or both numbers are signed. + [h4 Multiprecision-2.2.4 (Boost-1.58)]