mirror of
https://github.com/boostorg/multiprecision.git
synced 2026-02-20 02:42:26 +00:00
Fix conversions from long long to take long sized chunks.
Also fixed some bitmasks, and added feature-detection checks.
This commit is contained in:
@@ -59,10 +59,15 @@ namespace detail{
|
||||
template <unsigned digits10>
|
||||
struct gmp_float_imp
|
||||
{
|
||||
typedef mpl::list<long, long long> signed_types;
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
typedef mpl::list<long, long long> signed_types;
|
||||
typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
|
||||
typedef mpl::list<double, long double> float_types;
|
||||
typedef long exponent_type;
|
||||
#else
|
||||
typedef mpl::list<long> signed_types;
|
||||
typedef mpl::list<unsigned long> unsigned_types;
|
||||
#endif
|
||||
typedef mpl::list<double, long double> 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<unsigned long>(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<unsigned>::digits) - 1);
|
||||
unsigned long long mask = ((((1uLL << (std::numeric_limits<unsigned long>::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<unsigned>(i & mask));
|
||||
mpf_set_ui(t, static_cast<unsigned long>(i & mask));
|
||||
if(shift)
|
||||
mpf_mul_2exp(t, t, shift);
|
||||
mpf_add(m_data, m_data, t);
|
||||
shift += std::numeric_limits<unsigned>::digits;
|
||||
i >>= std::numeric_limits<unsigned>::digits;
|
||||
shift += std::numeric_limits<unsigned long>::digits;
|
||||
i >>= std::numeric_limits<unsigned long>::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<Digits10>& result, const gmp_float<Digits10>& v
|
||||
|
||||
struct gmp_int
|
||||
{
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
typedef mpl::list<long, long long> signed_types;
|
||||
typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
|
||||
#else
|
||||
typedef mpl::list<long> signed_types;
|
||||
typedef mpl::list<unsigned long> unsigned_types;
|
||||
#endif
|
||||
typedef mpl::list<double, long double> 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<unsigned long>(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<unsigned>::digits) - 1);
|
||||
unsigned long long mask = ((((1uLL << (std::numeric_limits<unsigned long>::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<unsigned>(i & mask));
|
||||
mpz_set_ui(t, static_cast<unsigned long>(i & mask));
|
||||
if(shift)
|
||||
mpz_mul_2exp(t, t, shift);
|
||||
mpz_add(m_data, m_data, t);
|
||||
shift += std::numeric_limits<unsigned>::digits;
|
||||
i >>= std::numeric_limits<unsigned>::digits;
|
||||
shift += std::numeric_limits<unsigned long>::digits;
|
||||
i >>= std::numeric_limits<unsigned long>::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<long, long long> signed_types;
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
typedef mpl::list<long, long long> signed_types;
|
||||
typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
|
||||
typedef mpl::list<double, long double> float_types;
|
||||
#else
|
||||
typedef mpl::list<long> signed_types;
|
||||
typedef mpl::list<unsigned long> unsigned_types;
|
||||
#endif
|
||||
typedef mpl::list<double, long double> 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<unsigned long>(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<unsigned>::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<unsigned>(i & mask), 1);
|
||||
if(shift)
|
||||
mpq_mul_2exp(t, t, shift);
|
||||
mpq_add(m_data, m_data, t);
|
||||
shift += std::numeric_limits<unsigned>::digits;
|
||||
i >>= std::numeric_limits<unsigned>::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)
|
||||
|
||||
@@ -55,8 +55,13 @@ struct mpfi_float_imp;
|
||||
template <unsigned digits10>
|
||||
struct mpfi_float_imp
|
||||
{
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
typedef mpl::list<long, long long> signed_types;
|
||||
typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
|
||||
#else
|
||||
typedef mpl::list<long> signed_types;
|
||||
typedef mpl::list<unsigned long> unsigned_types;
|
||||
#endif
|
||||
typedef mpl::list<double, long double> 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<unsigned>::digits) - 1);
|
||||
unsigned long long mask = (((1uLL << (std::numeric_limits<unsigned long>::digits - 1) - 1) << 1) | 1u);
|
||||
unsigned shift = 0;
|
||||
mpfi_t t;
|
||||
mpfi_init2(t, (std::max)(static_cast<unsigned>(std::numeric_limits<unsigned long long>::digits), static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10))));
|
||||
mpfi_init2(t, (std::max)(static_cast<unsigned>(std::numeric_limits<unsigned long long>::digits), static_cast<unsigned long>(multiprecision::detail::digits10_2_2(digits10))));
|
||||
mpfi_set_ui(m_data, 0);
|
||||
while(i)
|
||||
{
|
||||
mpfi_set_ui(t, static_cast<unsigned>(i & mask));
|
||||
mpfi_set_ui(t, static_cast<unsigned long>(i & mask));
|
||||
if(shift)
|
||||
mpfi_mul_2exp(t, t, shift);
|
||||
mpfi_add(m_data, m_data, t);
|
||||
shift += std::numeric_limits<unsigned>::digits;
|
||||
i >>= std::numeric_limits<unsigned>::digits;
|
||||
shift += std::numeric_limits<unsigned long>::digits;
|
||||
i >>= std::numeric_limits<unsigned long>::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)
|
||||
{
|
||||
|
||||
@@ -63,8 +63,13 @@ struct mpfr_float_imp;
|
||||
template <unsigned digits10>
|
||||
struct mpfr_float_imp<digits10, allocate_dynamic>
|
||||
{
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
typedef mpl::list<long, long long> signed_types;
|
||||
typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
|
||||
#else
|
||||
typedef mpl::list<long> signed_types;
|
||||
typedef mpl::list<unsigned long> unsigned_types;
|
||||
#endif
|
||||
typedef mpl::list<double, long double> float_types;
|
||||
typedef long exponent_type;
|
||||
|
||||
@@ -105,6 +110,7 @@ struct mpfr_float_imp<digits10, allocate_dynamic>
|
||||
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<digits10, allocate_dynamic>
|
||||
{
|
||||
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<unsigned>::digits) - 1);
|
||||
unsigned long long mask = (((1uLL << (std::numeric_limits<unsigned long>::digits - 1) - 1) << 1) | 1uLL);
|
||||
unsigned shift = 0;
|
||||
mpfr_t t;
|
||||
mpfr_init2(t, (std::max)(static_cast<unsigned>(std::numeric_limits<unsigned long long>::digits), static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10))));
|
||||
mpfr_init2(t, (std::max)(static_cast<unsigned>(std::numeric_limits<unsigned long long>::digits), static_cast<unsigned long>(multiprecision::detail::digits10_2_2(digits10))));
|
||||
mpfr_set_ui(m_data, 0, GMP_RNDN);
|
||||
while(i)
|
||||
{
|
||||
mpfr_set_ui(t, static_cast<unsigned>(i & mask), GMP_RNDN);
|
||||
mpfr_set_ui(t, static_cast<unsigned long>(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<unsigned>::digits;
|
||||
i >>= std::numeric_limits<unsigned>::digits;
|
||||
shift += std::numeric_limits<unsigned long>::digits;
|
||||
i >>= std::numeric_limits<unsigned long>::digits;
|
||||
}
|
||||
mpfr_clear(t);
|
||||
return *this;
|
||||
@@ -152,6 +158,7 @@ struct mpfr_float_imp<digits10, allocate_dynamic>
|
||||
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 <unsigned digits10>
|
||||
struct mpfr_float_imp<digits10, allocate_stack>
|
||||
{
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
typedef mpl::list<long, long long> signed_types;
|
||||
typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
|
||||
#else
|
||||
typedef mpl::list<long> signed_types;
|
||||
typedef mpl::list<unsigned long> unsigned_types;
|
||||
#endif
|
||||
typedef mpl::list<double, long double> float_types;
|
||||
typedef long exponent_type;
|
||||
|
||||
@@ -392,6 +404,7 @@ struct mpfr_float_imp<digits10, allocate_stack>
|
||||
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<digits10, allocate_stack>
|
||||
#else
|
||||
mpfr_float_imp& operator = (unsigned long long i)
|
||||
{
|
||||
unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
|
||||
unsigned long long mask = (((1uLL << (std::numeric_limits<unsigned long>::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<digits10, allocate_stack>
|
||||
mpfr_set_ui(m_data, 0, GMP_RNDN);
|
||||
while(i)
|
||||
{
|
||||
mpfr_set_ui(t, static_cast<unsigned>(i & mask), GMP_RNDN);
|
||||
mpfr_set_ui(t, static_cast<unsigned long>(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<unsigned>::digits;
|
||||
i >>= std::numeric_limits<unsigned>::digits;
|
||||
shift += std::numeric_limits<unsigned long>::digits;
|
||||
i >>= std::numeric_limits<unsigned long>::digits;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@@ -432,6 +445,7 @@ struct mpfr_float_imp<digits10, allocate_stack>
|
||||
mpfr_neg(m_data, m_data, GMP_RNDN);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
mpfr_float_imp& operator = (unsigned long i)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user