mirror of
https://github.com/boostorg/multiprecision.git
synced 2026-02-20 14:52:24 +00:00
Fix bounded variable precision cpp_int's.
1) Removed some constexpr optimizations which were causing the code to fail to spot that truncation/overflow had occurred. 2) Change min/max code for numeric_limits to work for bounded variable precision types (this needs more work as the current code relies on being able to create a fixed-precision allocator-free type of equivalent width. 3) Add tests for bounded variable precision integers. See: https://svn.boost.org/trac/boost/ticket/12798
This commit is contained in:
@@ -84,7 +84,7 @@ inline void add_unsigned(CppInt1& result, const CppInt2& a, const CppInt3& b) BO
|
||||
{
|
||||
// We overflowed, need to add one more limb:
|
||||
result.resize(x + 1, x + 1);
|
||||
if(CppInt1::variable || (result.size() > x))
|
||||
if(result.size() > x)
|
||||
result.limbs()[x] = static_cast<limb_type>(carry);
|
||||
}
|
||||
result.normalize();
|
||||
@@ -126,7 +126,7 @@ inline void add_unsigned(CppInt1& result, const CppInt2& a, const limb_type& o)
|
||||
// We overflowed, need to add one more limb:
|
||||
unsigned x = result.size();
|
||||
result.resize(x + 1, x + 1);
|
||||
if(CppInt1::variable || (result.size() > x))
|
||||
if(result.size() > x)
|
||||
result.limbs()[x] = static_cast<limb_type>(carry);
|
||||
}
|
||||
result.normalize();
|
||||
|
||||
@@ -220,7 +220,7 @@ void divide_unsigned_helper(
|
||||
//
|
||||
double_limb_type carry = 0;
|
||||
t.resize(y.size() + shift + 1, y.size() + shift);
|
||||
bool truncated_t = !CppInt1::variable && (t.size() != y.size() + shift + 1);
|
||||
bool truncated_t = (t.size() != y.size() + shift + 1);
|
||||
typename CppInt1::limb_pointer pt = t.limbs();
|
||||
for(unsigned i = 0; i < shift; ++i)
|
||||
pt[i] = 0;
|
||||
|
||||
@@ -23,7 +23,7 @@ inline boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinB
|
||||
{
|
||||
// Bounded and signed.
|
||||
typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> result_type;
|
||||
typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, Allocator>, ExpressionTemplates> ui_type;
|
||||
typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MaxBits, MaxBits, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked>, ExpressionTemplates> ui_type;
|
||||
static const result_type val = -result_type(~ui_type(0));
|
||||
return val;
|
||||
}
|
||||
@@ -62,7 +62,7 @@ inline boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinB
|
||||
{
|
||||
// Bounded and signed.
|
||||
typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>, ExpressionTemplates> result_type;
|
||||
typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MinBits, MaxBits, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, Allocator>, ExpressionTemplates> ui_type;
|
||||
typedef boost::multiprecision::number<boost::multiprecision::cpp_int_backend<MaxBits, MaxBits, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked>, ExpressionTemplates> ui_type;
|
||||
static const result_type val = ~ui_type(0);
|
||||
return val;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit
|
||||
{
|
||||
unsigned i = result.size();
|
||||
result.resize(i + 1, i + 1);
|
||||
if(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::variable || (result.size() > i))
|
||||
if(result.size() > i)
|
||||
result.limbs()[i] = static_cast<limb_type>(carry);
|
||||
}
|
||||
result.sign(a.sign());
|
||||
@@ -157,7 +157,7 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit
|
||||
BOOST_ASSERT(carry <= (cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::max_limb_value));
|
||||
}
|
||||
resize_for_carry(result, as + bs); // May throw if checking is enabled
|
||||
if(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::variable || (i + bs < result.size()))
|
||||
if(i + bs < result.size())
|
||||
pr[i + bs] = static_cast<limb_type>(carry);
|
||||
carry = 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user