summaryrefslogtreecommitdiff
path: root/boost/multiprecision/cpp_int/multiply.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/multiprecision/cpp_int/multiply.hpp')
-rw-r--r--boost/multiprecision/cpp_int/multiply.hpp22
1 files changed, 15 insertions, 7 deletions
diff --git a/boost/multiprecision/cpp_int/multiply.hpp b/boost/multiprecision/cpp_int/multiply.hpp
index afe1db7a9f..151b2294c7 100644
--- a/boost/multiprecision/cpp_int/multiply.hpp
+++ b/boost/multiprecision/cpp_int/multiply.hpp
@@ -64,10 +64,10 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit
template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
inline void resize_for_carry(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& /*result*/, unsigned /*required*/){}
-template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
-inline void resize_for_carry(cpp_int_backend<MinBits1, MaxBits1, SignType1, checked, void>& result, unsigned required)
+template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, class Allocator1>
+inline void resize_for_carry(cpp_int_backend<MinBits1, MaxBits1, SignType1, checked, Allocator1>& result, unsigned required)
{
- if(result.size() != required)
+ if(result.size() < required)
result.resize(required, required);
}
@@ -136,7 +136,8 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit
for(unsigned i = 0; i < as; ++i)
{
unsigned inner_limit = cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::variable ? bs : (std::min)(result.size() - i, bs);
- for(unsigned j = 0; j < inner_limit; ++j)
+ unsigned j;
+ for(j = 0; j < inner_limit; ++j)
{
BOOST_ASSERT(i+j < result.size());
#if (!defined(__GLIBCXX__) && !defined(__GLIBCPP__)) || !BOOST_WORKAROUND(BOOST_GCC_VERSION, <= 50100)
@@ -156,9 +157,16 @@ inline typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBit
carry >>= cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::limb_bits;
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(i + bs < result.size())
- pr[i + bs] = static_cast<limb_type>(carry);
+ if(carry)
+ {
+ resize_for_carry(result, i + j + 1); // May throw if checking is enabled
+ if(i + j < result.size())
+#ifdef __MSVC_RUNTIME_CHECKS
+ pr[i + j] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
+#else
+ pr[i + j] = static_cast<limb_type>(carry);
+#endif
+ }
carry = 0;
}
result.normalize();