From 72c817e985091d34894c22cfcd492ba73c7e7fb9 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Sat, 16 May 2015 11:16:11 +0100 Subject: [PATCH] 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