From db83a1c4add6f8124a4113d46a54564bd3766044 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Thu, 12 Jan 2012 11:55:09 +0000 Subject: [PATCH] Tentative rename of packed_cpp_int to fixed_int. [SVN r76428] --- .../boost/multiprecision/packed_cpp_int.hpp | 399 +++++++++--------- performance/performance_test.cpp | 12 +- test/Jamfile.v2 | 18 +- test/packed_int_test.cpp | 6 +- test/test_arithmetic.cpp | 18 +- test/test_int_io.cpp | 22 +- 6 files changed, 249 insertions(+), 226 deletions(-) diff --git a/include/boost/multiprecision/packed_cpp_int.hpp b/include/boost/multiprecision/packed_cpp_int.hpp index 6dbc8657..0bbc2fa7 100644 --- a/include/boost/multiprecision/packed_cpp_int.hpp +++ b/include/boost/multiprecision/packed_cpp_int.hpp @@ -18,7 +18,7 @@ namespace boost{ namespace multiprecision{ template -struct packed_cpp_int +struct fixed_int { typedef mpl::list signed_types; typedef mpl::list unsigned_types; @@ -33,37 +33,37 @@ struct packed_cpp_int BOOST_STATIC_CONSTANT(limb_type, sign_bit_mask = 1 << ((Bits % limb_bits ? Bits % limb_bits : limb_bits) - 1)); typedef boost::array data_type; - packed_cpp_int(){} - packed_cpp_int(const packed_cpp_int& o) + fixed_int(){} + fixed_int(const fixed_int& o) { m_value = o.m_value; } #ifndef BOOST_NO_RVALUE_REFERENCES - packed_cpp_int(packed_cpp_int&& o) : m_value(o.m_value) {} + fixed_int(fixed_int&& o) : m_value(o.m_value) {} #endif - packed_cpp_int& operator = (const packed_cpp_int& o) + fixed_int& operator = (const fixed_int& o) { m_value = o.m_value; return *this; } - packed_cpp_int& operator = (boost::uint32_t i) + fixed_int& operator = (boost::uint32_t i) { m_value[limb_count - 1] = i; for(int j = limb_count - 2; j >= 0; --j) m_value[j] = 0; - m_value[0] &= packed_cpp_int::upper_limb_mask; + m_value[0] &= fixed_int::upper_limb_mask; return *this; } - packed_cpp_int& operator = (boost::int32_t i) + fixed_int& operator = (boost::int32_t i) { m_value[limb_count - 1] = i; // sign extend: for(int j = limb_count - 2; j >= 0; --j) m_value[j] = i < 0 ? max_limb_value : 0; - m_value[0] &= packed_cpp_int::upper_limb_mask; + m_value[0] &= fixed_int::upper_limb_mask; return *this; } - packed_cpp_int& operator = (boost::uintmax_t i) + fixed_int& operator = (boost::uintmax_t i) { BOOST_STATIC_ASSERT(sizeof(i) % sizeof(limb_type) == 0); boost::uintmax_t mask = max_limb_value; @@ -76,10 +76,10 @@ struct packed_cpp_int } for(int j = static_cast(limb_count) - static_cast(sizeof(boost::intmax_t) / sizeof(limb_type)) - 1; j >= 0; --j) m_value[j] = 0; - m_value[0] &= packed_cpp_int::upper_limb_mask; + m_value[0] &= fixed_int::upper_limb_mask; return *this; } - packed_cpp_int& operator = (boost::intmax_t i) + fixed_int& operator = (boost::intmax_t i) { BOOST_STATIC_ASSERT(sizeof(i) % sizeof(limb_type) == 0); boost::uintmax_t mask = max_limb_value; @@ -92,10 +92,10 @@ struct packed_cpp_int } for(int j = static_cast(limb_count) - static_cast(sizeof(boost::intmax_t) / sizeof(limb_type)) - 1; j >= 0; --j) m_value[j] = i < 0 ? max_limb_value : 0; - m_value[0] &= packed_cpp_int::upper_limb_mask; + m_value[0] &= fixed_int::upper_limb_mask; return *this; } - packed_cpp_int& operator = (long double a) + fixed_int& operator = (long double a) { BOOST_STATIC_ASSERT(Bits >= (unsigned)std::numeric_limits::digits); using std::frexp; @@ -138,10 +138,10 @@ struct packed_cpp_int left_shift(*this, e); else if(e < 0) right_shift(*this, -e); - data()[0] &= packed_cpp_int::upper_limb_mask; + data()[0] &= fixed_int::upper_limb_mask; return *this; } - packed_cpp_int& operator = (const char* s) + fixed_int& operator = (const char* s) { std::size_t n = s ? std::strlen(s) : 0; *this = static_cast(0u); @@ -186,7 +186,7 @@ struct packed_cpp_int val = max_limb_value; if(val > radix) { - m_value[0] &= packed_cpp_int::upper_limb_mask; + m_value[0] &= fixed_int::upper_limb_mask; return *this; // TODO raise an exception here? } m_value[limb_count - 1] |= val; @@ -210,12 +210,12 @@ struct packed_cpp_int } } } - m_value[0] &= packed_cpp_int::upper_limb_mask; + m_value[0] &= fixed_int::upper_limb_mask; if(isneg) negate(); return *this; } - void swap(packed_cpp_int& o) + void swap(fixed_int& o) { std::swap(m_value, o.m_value); } @@ -232,7 +232,7 @@ struct packed_cpp_int { boost::uint32_t shift = base == 8 ? 3 : 4; boost::uint32_t mask = static_cast((1u << shift) - 1); - packed_cpp_int t(*this); + fixed_int t(*this); for(unsigned i = 0; i < Bits / shift; ++i) { char c = '0' + (t.data()[limb_count-1] & mask); @@ -264,8 +264,8 @@ struct packed_cpp_int } else { - packed_cpp_int t(*this); - packed_cpp_int ten, r; + fixed_int t(*this); + fixed_int ten, r; ten = boost::uint32_t(1000000000); bool neg = false; if(Signed && (t.data()[0] & sign_bit_mask)) @@ -281,7 +281,7 @@ struct packed_cpp_int { while(get_sign(t) != 0) { - packed_cpp_int t2; + fixed_int t2; divide_unsigned_helper(t2, t, ten, r); t = t2; boost::uint32_t v = r.data()[limb_count - 1]; @@ -307,15 +307,15 @@ struct packed_cpp_int void negate() { boost::uintmax_t carry = 1; - for(int i = packed_cpp_int::limb_count - 1; i >= 0; --i) + for(int i = fixed_int::limb_count - 1; i >= 0; --i) { carry += static_cast(~m_value[i]); m_value[i] = static_cast(carry); carry >>= limb_bits; } - m_value[0] &= packed_cpp_int::upper_limb_mask; + m_value[0] &= fixed_int::upper_limb_mask; } - int compare(const packed_cpp_int& o)const + int compare(const fixed_int& o)const { int result = 0; if(Signed && ((m_value[0] & sign_bit_mask) != (o.data()[0] & sign_bit_mask))) @@ -336,7 +336,7 @@ struct packed_cpp_int typename enable_if, int>::type compare(Arithmatic i)const { // braindead version: - packed_cpp_int t; + fixed_int t; t = i; return compare(t); } @@ -347,40 +347,40 @@ private: }; template -inline void add(packed_cpp_int& result, const packed_cpp_int& o) +inline void add(fixed_int& result, const fixed_int& o) { add(result, result, o); } template -inline void add(packed_cpp_int& result, const packed_cpp_int& a, const packed_cpp_int& b) +inline void add(fixed_int& result, const fixed_int& a, const fixed_int& b) { // Addition using modular arithmatic. // Nothing fancy, just let uintmax_t take the strain: boost::uintmax_t carry = 0; - for(int i = packed_cpp_int::limb_count - 1; i >= 0; --i) + for(int i = fixed_int::limb_count - 1; i >= 0; --i) { carry += static_cast(a.data()[i]) + static_cast(b.data()[i]); - result.data()[i] = static_cast::limb_type>(carry); - carry >>= packed_cpp_int::limb_bits; + result.data()[i] = static_cast::limb_type>(carry); + carry >>= fixed_int::limb_bits; } - result.data()[0] &= packed_cpp_int::upper_limb_mask; + result.data()[0] &= fixed_int::upper_limb_mask; } template -inline void add(packed_cpp_int& result, const boost::uint32_t& o) +inline void add(fixed_int& result, const boost::uint32_t& o) { // Addition using modular arithmatic. // Nothing fancy, just let uintmax_t take the strain: boost::uintmax_t carry = o; - for(int i = packed_cpp_int::limb_count - 1; carry && i >= 0; --i) + for(int i = fixed_int::limb_count - 1; carry && i >= 0; --i) { carry += static_cast(result.data()[i]); - result.data()[i] = static_cast::limb_type>(carry); - carry >>= packed_cpp_int::limb_bits; + result.data()[i] = static_cast::limb_type>(carry); + carry >>= fixed_int::limb_bits; } - result.data()[0] &= packed_cpp_int::upper_limb_mask; + result.data()[0] &= fixed_int::upper_limb_mask; } template -inline void add(packed_cpp_int& result, const boost::int32_t& o) +inline void add(fixed_int& result, const boost::int32_t& o) { if(o < 0) subtract(result, static_cast(-o)); @@ -388,24 +388,24 @@ inline void add(packed_cpp_int& result, const boost::int32_t& o) add(result, static_cast(o)); } template -inline void subtract(packed_cpp_int& result, const boost::uint32_t& o) +inline void subtract(fixed_int& result, const boost::uint32_t& o) { // Subtract using modular arithmatic. // This is the same code as for addition, with the twist that we negate o "on the fly": - boost::uintmax_t carry = static_cast(result.data()[packed_cpp_int::limb_count - 1]) + boost::uintmax_t carry = static_cast(result.data()[fixed_int::limb_count - 1]) + 1uLL + static_cast(~o); - result.data()[packed_cpp_int::limb_count - 1] = static_cast::limb_type>(carry); - carry >>= packed_cpp_int::limb_bits; - for(int i = packed_cpp_int::limb_count - 2; i >= 0; --i) + result.data()[fixed_int::limb_count - 1] = static_cast::limb_type>(carry); + carry >>= fixed_int::limb_bits; + for(int i = fixed_int::limb_count - 2; i >= 0; --i) { carry += static_cast(result.data()[i]) + 0xFFFFFFFF; - result.data()[i] = static_cast::limb_type>(carry); - carry >>= packed_cpp_int::limb_bits; + result.data()[i] = static_cast::limb_type>(carry); + carry >>= fixed_int::limb_bits; } - result.data()[0] &= packed_cpp_int::upper_limb_mask; + result.data()[0] &= fixed_int::upper_limb_mask; } template -inline void subtract(packed_cpp_int& result, const boost::int32_t& o) +inline void subtract(fixed_int& result, const boost::int32_t& o) { if(o) { @@ -416,90 +416,90 @@ inline void subtract(packed_cpp_int& result, const boost::int32_t& } } template -inline void increment(packed_cpp_int& result) +inline void increment(fixed_int& result) { static const boost::uint32_t one = 1; add(result, one); } template -inline void decrement(packed_cpp_int& result) +inline void decrement(fixed_int& result) { static const boost::uint32_t one = 1; subtract(result, one); } template -inline void subtract(packed_cpp_int& result, const packed_cpp_int& o) +inline void subtract(fixed_int& result, const fixed_int& o) { subtract(result, result, o); } template -inline void subtract(packed_cpp_int& result, const packed_cpp_int& a, const packed_cpp_int& b) +inline void subtract(fixed_int& result, const fixed_int& a, const fixed_int& b) { // Subtract using modular arithmatic. // This is the same code as for addition, with the twist that we negate b "on the fly": boost::uintmax_t carry = 1; - for(int i = packed_cpp_int::limb_count - 1; i >= 0; --i) + for(int i = fixed_int::limb_count - 1; i >= 0; --i) { carry += static_cast(a.data()[i]) + static_cast(~b.data()[i]); - result.data()[i] = static_cast::limb_type>(carry); - carry >>= packed_cpp_int::limb_bits; + result.data()[i] = static_cast::limb_type>(carry); + carry >>= fixed_int::limb_bits; } - result.data()[0] &= packed_cpp_int::upper_limb_mask; + result.data()[0] &= fixed_int::upper_limb_mask; } template -inline void multiply(packed_cpp_int& result, const packed_cpp_int& a, const packed_cpp_int& b) +inline void multiply(fixed_int& result, const fixed_int& a, const fixed_int& b) { // Very simple long multiplication, only usable for small numbers of limb_type's // but that's the typical use case for this type anyway: if(&result == &a) { - packed_cpp_int t(a); + fixed_int t(a); multiply(result, t, b); return; } if(&result == &b) { - packed_cpp_int t(b); + fixed_int t(b); multiply(result, a, t); return; } boost::uintmax_t carry = 0; - for(unsigned i = 0; i < packed_cpp_int::limb_count; ++i) + for(unsigned i = 0; i < fixed_int::limb_count; ++i) result.data()[i] = 0; - for(int i = packed_cpp_int::limb_count - 1; i >= 0; --i) + for(int i = fixed_int::limb_count - 1; i >= 0; --i) { - for(int j = packed_cpp_int::limb_count - 1; j >= static_cast(packed_cpp_int::limb_count) - i - 1; --j) + for(int j = fixed_int::limb_count - 1; j >= static_cast(fixed_int::limb_count) - i - 1; --j) { carry += static_cast(a.data()[i]) * static_cast(b.data()[j]); - carry += result.data()[i + j + 1 - packed_cpp_int::limb_count]; - result.data()[i + j + 1 - packed_cpp_int::limb_count] = static_cast::limb_type>(carry); - carry >>= packed_cpp_int::limb_bits; + carry += result.data()[i + j + 1 - fixed_int::limb_count]; + result.data()[i + j + 1 - fixed_int::limb_count] = static_cast::limb_type>(carry); + carry >>= fixed_int::limb_bits; } carry = 0; } - result.data()[0] &= packed_cpp_int::upper_limb_mask; + result.data()[0] &= fixed_int::upper_limb_mask; } template -inline void multiply(packed_cpp_int& result, const packed_cpp_int& a) +inline void multiply(fixed_int& result, const fixed_int& a) { // There is no in-place multiply: - packed_cpp_int b(result); + fixed_int b(result); multiply(result, b, a); } template -inline void multiply(packed_cpp_int& result, const boost::uint32_t& a) +inline void multiply(fixed_int& result, const boost::uint32_t& a) { boost::uintmax_t carry = 0; - for(int i = packed_cpp_int::limb_count - 1; i >= 0; --i) + for(int i = fixed_int::limb_count - 1; i >= 0; --i) { carry += static_cast(result.data()[i]) * static_cast(a); - result.data()[i] = static_cast::limb_type>(carry); - carry >>= packed_cpp_int::limb_bits; + result.data()[i] = static_cast::limb_type>(carry); + carry >>= fixed_int::limb_bits; } - result.data()[0] &= packed_cpp_int::upper_limb_mask; + result.data()[0] &= fixed_int::upper_limb_mask; } template -inline void multiply(packed_cpp_int& result, const boost::int32_t& a) +inline void multiply(fixed_int& result, const boost::int32_t& a) { if(a > 0) multiply(result, static_cast(a)); @@ -512,15 +512,15 @@ inline void multiply(packed_cpp_int& result, const boost::int32_t& /* template -boost::uint32_t bitcount(const packed_cpp_int& a) +boost::uint32_t bitcount(const fixed_int& a) { // returns the location of the MSB in a: boost::uint32_t i = 0; - for(; (i < packed_cpp_int::limb_count) && (a.data()[i] == 0); ++i){} - boost::uint32_t count = (packed_cpp_int::limb_count - i) * packed_cpp_int::limb_bits; + for(; (i < fixed_int::limb_count) && (a.data()[i] == 0); ++i){} + boost::uint32_t count = (fixed_int::limb_count - i) * fixed_int::limb_bits; if(!count) return count; // no bits are set, value is zero - boost::uint32_t mask = static_cast(1u) << (packed_cpp_int::limb_bits - 1); + boost::uint32_t mask = static_cast(1u) << (fixed_int::limb_bits - 1); while((a.data()[i] & mask) == 0) { --count; @@ -529,17 +529,17 @@ boost::uint32_t bitcount(const packed_cpp_int& a) return count; } template -void divide_unsigned_helper(packed_cpp_int& result, const packed_cpp_int& x, const packed_cpp_int& y, packed_cpp_int& r) +void divide_unsigned_helper(fixed_int& result, const fixed_int& x, const fixed_int& y, fixed_int& r) { if((&result == &x) || (&r == &x)) { - packed_cpp_int t(x); + fixed_int t(x); divide_unsigned_helper(result, t, y, r); return; } if((&result == &y) || (&r == &y)) { - packed_cpp_int t(y); + fixed_int t(y); divide_unsigned_helper(result, x, t, r); return; } @@ -564,7 +564,7 @@ void divide_unsigned_helper(packed_cpp_int& result, const packed_c if(&result == &r) { - packed_cpp_int rem; + fixed_int rem; divide_unsigned_helper(result, x, y, rem); r = rem; return; @@ -588,11 +588,11 @@ void divide_unsigned_helper(packed_cpp_int& result, const packed_c } // Together mask_index and mask give us the bit we may be about to set in the result: - boost::uint32_t mask_index = packed_cpp_int::limb_count - 1 - n / packed_cpp_int::limb_bits; - boost::uint32_t mask = static_cast(1u) << n % packed_cpp_int::limb_bits; - packed_cpp_int t(y); + boost::uint32_t mask_index = fixed_int::limb_count - 1 - n / fixed_int::limb_bits; + boost::uint32_t mask = static_cast(1u) << n % fixed_int::limb_bits; + fixed_int t(y); left_shift(t, n); - while(mask_index < packed_cpp_int::limb_count) + while(mask_index < fixed_int::limb_count) { int comp = r.compare(t); if(comp >= 0) @@ -606,28 +606,46 @@ void divide_unsigned_helper(packed_cpp_int& result, const packed_c if(0 == (mask >>= 1)) { ++mask_index; - mask = static_cast(1u) << (packed_cpp_int::limb_bits - 1); + mask = static_cast(1u) << (fixed_int::limb_bits - 1); } } BOOST_ASSERT(r.compare(y) < 0); // remainder must be less than the divisor or our code has failed } */ template -void divide_unsigned_helper(packed_cpp_int& result, const packed_cpp_int& x, const packed_cpp_int& y, packed_cpp_int& r) +void divide_unsigned_helper(fixed_int& result, const fixed_int& x, const fixed_int& y, fixed_int& r) { if((&result == &x) || (&r == &x)) { - packed_cpp_int t(x); + fixed_int t(x); divide_unsigned_helper(result, t, y, r); return; } if((&result == &y) || (&r == &y)) { - packed_cpp_int t(y); + fixed_int t(y); divide_unsigned_helper(result, x, t, r); return; } + /* + Very simple, fairly braindead long division. + Start by setting the remainder equal to x, and the + result equal to 0. Then in each loop we calculate our + "best guess" for how many times y divides into r, + add our guess to the result, and subtract guess*y + from the remainder r. One wrinckle is that the remainder + may go negative, in which case we subtract the current guess + from the result rather than adding. The value of the guess + is determined by dividing the most-significant-limb of the + current remainder by the most-significant-limb of y. + + Note that there are more efficient algorithms than this + available, in particular see Knuth Vol 2. However for small + numbers of limbs this generally outperforms the alternatives + and avoids the normalisation step which would require extra storage. + */ + using default_ops::subtract; @@ -648,7 +666,7 @@ void divide_unsigned_helper(packed_cpp_int& result, const packed_c if(&result == &r) { - packed_cpp_int rem; + fixed_int rem; divide_unsigned_helper(result, x, y, rem); r = rem; return; @@ -673,24 +691,24 @@ void divide_unsigned_helper(packed_cpp_int& result, const packed_c while(y.data()[y_order] == 0) ++y_order; - packed_cpp_int t; + fixed_int t; bool r_neg = false; // // See if we can short-circuit long division, and use basic arithmetic instead: // - if(r_order == packed_cpp_int::limb_count - 1) + if(r_order == fixed_int::limb_count - 1) { - result = r.data()[packed_cpp_int::limb_count - 1] / y.data()[packed_cpp_int::limb_count - 1]; - r = x.data()[packed_cpp_int::limb_count - 1] % y.data()[packed_cpp_int::limb_count - 1]; + result = r.data()[fixed_int::limb_count - 1] / y.data()[fixed_int::limb_count - 1]; + r = x.data()[fixed_int::limb_count - 1] % y.data()[fixed_int::limb_count - 1]; return; } - else if(r_order == packed_cpp_int::limb_count - 2) + else if(r_order == fixed_int::limb_count - 2) { unsigned long long a, b; - a = (static_cast(r.data()[r_order]) << packed_cpp_int::limb_bits) | r.data()[r_order + 1]; - b = y_order < packed_cpp_int::limb_count - 1 ? - (static_cast(y.data()[y_order]) << packed_cpp_int::limb_bits) | y.data()[y_order + 1] + a = (static_cast(r.data()[r_order]) << fixed_int::limb_bits) | r.data()[r_order + 1]; + b = y_order < fixed_int::limb_count - 1 ? + (static_cast(y.data()[y_order]) << fixed_int::limb_bits) | y.data()[y_order + 1] : y.data()[y_order]; result = a / b; r = a % b; @@ -708,13 +726,13 @@ void divide_unsigned_helper(packed_cpp_int& result, const packed_c // Calculate our best guess for how many times y divides into r: // boost::uint32_t guess; - if((r.data()[r_order] <= y.data()[y_order]) && (r_order < packed_cpp_int::limb_count - 1)) + if((r.data()[r_order] <= y.data()[y_order]) && (r_order < fixed_int::limb_count - 1)) { unsigned long long a, b, v; - a = (static_cast(r.data()[r_order]) << packed_cpp_int::limb_bits) | r.data()[r_order + 1]; + a = (static_cast(r.data()[r_order]) << fixed_int::limb_bits) | r.data()[r_order + 1]; b = y.data()[y_order]; v = a / b; - if(v > packed_cpp_int::max_limb_value) + if(v > fixed_int::max_limb_value) guess = 1; else { @@ -724,14 +742,19 @@ void divide_unsigned_helper(packed_cpp_int& result, const packed_c } else { - guess = r.data()[r_order] / y.data()[y_order]; + unsigned long long a, b, v; + a = (r_order < fixed_int::limb_count - 1) ? (static_cast(r.data()[r_order]) << fixed_int::limb_bits) | r.data()[r_order + 1] : r.data()[r_order]; + b = (y_order < fixed_int::limb_count - 1) ? (static_cast(y.data()[y_order]) << fixed_int::limb_bits) | y.data()[y_order + 1] : (static_cast(y.data()[y_order]) << fixed_int::limb_bits); + v = a / b; + guess = static_cast::limb_type>(v); + //guess = r.data()[r_order] / y.data()[y_order]; } // // Update result: // boost::uint32_t shift = y_order - r_order; t = boost::uint32_t(0); - t.data()[packed_cpp_int::limb_count - 1 - shift] = guess; + t.data()[fixed_int::limb_count - 1 - shift] = guess; if(r_neg) subtract(result, t); else @@ -741,20 +764,20 @@ void divide_unsigned_helper(packed_cpp_int& result, const packed_c // rather than a full O(N^2) multiply: // boost::uintmax_t carry = 0; - for(unsigned i = packed_cpp_int::limb_count - 1; i > packed_cpp_int::limb_count - shift - 1; --i) + for(unsigned i = fixed_int::limb_count - 1; i > fixed_int::limb_count - shift - 1; --i) t.data()[i] = 0; - for(int i = packed_cpp_int::limb_count - 1; i >= static_cast(shift); --i) + for(int i = fixed_int::limb_count - 1; i >= static_cast(shift); --i) { carry += static_cast(y.data()[i]) * static_cast(guess); - t.data()[i - shift] = static_cast::limb_type>(carry); - carry >>= packed_cpp_int::limb_bits; + t.data()[i - shift] = static_cast::limb_type>(carry); + carry >>= fixed_int::limb_bits; } - t.data()[0] &= packed_cpp_int::upper_limb_mask; + t.data()[0] &= fixed_int::upper_limb_mask; // // Update r: // subtract(r, t); - if(r.data()[0] & packed_cpp_int::sign_bit_mask) + if(r.data()[0] & fixed_int::sign_bit_mask) { r.negate(); r_neg = !r_neg; @@ -777,29 +800,29 @@ void divide_unsigned_helper(packed_cpp_int& result, const packed_c } template -inline void divide(packed_cpp_int& result, const packed_cpp_int& a, const packed_cpp_int& b) +inline void divide(fixed_int& result, const fixed_int& a, const fixed_int& b) { - packed_cpp_int r; - if(Signed && (a.data()[0] & packed_cpp_int::sign_bit_mask)) + fixed_int r; + if(Signed && (a.data()[0] & fixed_int::sign_bit_mask)) { - if(Signed && (b.data()[0] & packed_cpp_int::sign_bit_mask)) + if(Signed && (b.data()[0] & fixed_int::sign_bit_mask)) { - packed_cpp_int t1(a), t2(b); + fixed_int t1(a), t2(b); t1.negate(); t2.negate(); divide_unsigned_helper(result, t1, t2, r); } else { - packed_cpp_int t(a); + fixed_int t(a); t.negate(); divide_unsigned_helper(result, t, b, r); result.negate(); } } - else if(Signed && (b.data()[0] & packed_cpp_int::sign_bit_mask)) + else if(Signed && (b.data()[0] & fixed_int::sign_bit_mask)) { - packed_cpp_int t(b); + fixed_int t(b); t.negate(); divide_unsigned_helper(result, a, t, r); result.negate(); @@ -810,21 +833,21 @@ inline void divide(packed_cpp_int& result, const packed_cpp_int -inline void divide(packed_cpp_int& result, const packed_cpp_int& b) +inline void divide(fixed_int& result, const fixed_int& b) { // There is no in place divide: - packed_cpp_int a(result); + fixed_int a(result); divide(result, a, b); } template -inline void modulus(packed_cpp_int& result, const packed_cpp_int& a, const packed_cpp_int& b) +inline void modulus(fixed_int& result, const fixed_int& a, const fixed_int& b) { - packed_cpp_int r; - if(Signed && (a.data()[0] & packed_cpp_int::sign_bit_mask)) + fixed_int r; + if(Signed && (a.data()[0] & fixed_int::sign_bit_mask)) { - if(Signed && (b.data()[0] & packed_cpp_int::sign_bit_mask)) + if(Signed && (b.data()[0] & fixed_int::sign_bit_mask)) { - packed_cpp_int t1(a), t2(b); + fixed_int t1(a), t2(b); t1.negate(); t2.negate(); divide_unsigned_helper(r, t1, t2, result); @@ -832,15 +855,15 @@ inline void modulus(packed_cpp_int& result, const packed_cpp_int t(a); + fixed_int t(a); t.negate(); divide_unsigned_helper(r, t, b, result); result.negate(); } } - else if(Signed && (b.data()[0] & packed_cpp_int::sign_bit_mask)) + else if(Signed && (b.data()[0] & fixed_int::sign_bit_mask)) { - packed_cpp_int t(b); + fixed_int t(b); t.negate(); divide_unsigned_helper(r, a, t, result); } @@ -850,100 +873,100 @@ inline void modulus(packed_cpp_int& result, const packed_cpp_int -inline void modulus(packed_cpp_int& result, const packed_cpp_int& b) +inline void modulus(fixed_int& result, const fixed_int& b) { // There is no in place divide: - packed_cpp_int a(result); + fixed_int a(result); modulus(result, a, b); } template -inline void bitwise_and(packed_cpp_int& result, const packed_cpp_int& o) +inline void bitwise_and(fixed_int& result, const fixed_int& o) { - for(typename packed_cpp_int::data_type::size_type i = 0; i < packed_cpp_int::limb_count; ++i) + for(typename fixed_int::data_type::size_type i = 0; i < fixed_int::limb_count; ++i) result.data()[i] &= o.data()[i]; } template -inline void bitwise_or(packed_cpp_int& result, const packed_cpp_int& o) +inline void bitwise_or(fixed_int& result, const fixed_int& o) { - for(typename packed_cpp_int::data_type::size_type i = 0; i < packed_cpp_int::limb_count; ++i) + for(typename fixed_int::data_type::size_type i = 0; i < fixed_int::limb_count; ++i) result.data()[i] |= o.data()[i]; } template -inline void bitwise_xor(packed_cpp_int& result, const packed_cpp_int& o) +inline void bitwise_xor(fixed_int& result, const fixed_int& o) { - for(typename packed_cpp_int::data_type::size_type i = 0; i < packed_cpp_int::limb_count; ++i) + for(typename fixed_int::data_type::size_type i = 0; i < fixed_int::limb_count; ++i) result.data()[i] ^= o.data()[i]; - result.data()[0] &= packed_cpp_int::upper_limb_mask; + result.data()[0] &= fixed_int::upper_limb_mask; } template -inline void complement(packed_cpp_int& result, const packed_cpp_int& o) +inline void complement(fixed_int& result, const fixed_int& o) { - for(typename packed_cpp_int::data_type::size_type i = 0; i < packed_cpp_int::limb_count; ++i) + for(typename fixed_int::data_type::size_type i = 0; i < fixed_int::limb_count; ++i) result.data()[i] = ~o.data()[i]; - result.data()[0] &= packed_cpp_int::upper_limb_mask; + result.data()[0] &= fixed_int::upper_limb_mask; } template -inline void left_shift(packed_cpp_int& result, boost::uintmax_t s) +inline void left_shift(fixed_int& result, boost::uintmax_t s) { if(s >= Bits) { result = static_cast(0); return; } - boost::uint32_t offset = static_cast(s / packed_cpp_int::limb_bits); - boost::uint32_t shift = static_cast(s % packed_cpp_int::limb_bits); + boost::uint32_t offset = static_cast(s / fixed_int::limb_bits); + boost::uint32_t shift = static_cast(s % fixed_int::limb_bits); unsigned i = 0; if(shift) { // This code only works when shift is non-zero, otherwise we invoke undefined behaviour! - for(; i + offset + 1 < packed_cpp_int::limb_count; ++i) + for(; i + offset + 1 < fixed_int::limb_count; ++i) { result.data()[i] = result.data()[i+offset] << shift; - result.data()[i] |= result.data()[i+offset+1] >> (packed_cpp_int::limb_bits - shift); + result.data()[i] |= result.data()[i+offset+1] >> (fixed_int::limb_bits - shift); } result.data()[i] = result.data()[i+offset] << shift; ++i; - for(; i < packed_cpp_int::limb_count; ++i) + for(; i < fixed_int::limb_count; ++i) result.data()[i] = 0; } else { - for(; i + offset < packed_cpp_int::limb_count; ++i) + for(; i + offset < fixed_int::limb_count; ++i) result.data()[i] = result.data()[i+offset]; - for(; i < packed_cpp_int::limb_count; ++i) + for(; i < fixed_int::limb_count; ++i) result.data()[i] = 0; } - result.data()[0] &= packed_cpp_int::upper_limb_mask; + result.data()[0] &= fixed_int::upper_limb_mask; } template -inline void right_shift(packed_cpp_int& result, boost::uintmax_t s) +inline void right_shift(fixed_int& result, boost::uintmax_t s) { - boost::uint32_t fill = (Signed && (result.data()[0] & packed_cpp_int::sign_bit_mask)) ? packed_cpp_int::max_limb_value : 0u; + boost::uint32_t fill = (Signed && (result.data()[0] & fixed_int::sign_bit_mask)) ? fixed_int::max_limb_value : 0u; if(s >= Bits) { - for(unsigned i = 0; i < packed_cpp_int::limb_count; ++i) + for(unsigned i = 0; i < fixed_int::limb_count; ++i) result.data()[i] = fill; return; } - boost::uint32_t offset = static_cast(s / packed_cpp_int::limb_bits); - boost::uint32_t shift = static_cast(s % packed_cpp_int::limb_bits); - int i = packed_cpp_int::limb_count - 1; + boost::uint32_t offset = static_cast(s / fixed_int::limb_bits); + boost::uint32_t shift = static_cast(s % fixed_int::limb_bits); + int i = fixed_int::limb_count - 1; if(shift) { // This code only works for non-zero shift, otherwise we invoke undefined behaviour! - if(fill && (Bits % packed_cpp_int::limb_bits)) + if(fill && (Bits % fixed_int::limb_bits)) { // We need to sign extend the leftmost bits, otherwise we may shift zeros into the result: - result.data()[0] |= fill << (Bits % packed_cpp_int::limb_bits); + result.data()[0] |= fill << (Bits % fixed_int::limb_bits); } for(; i - offset > 0; --i) { result.data()[i] = result.data()[i-offset] >> shift; - result.data()[i] |= result.data()[i-offset-1] << (packed_cpp_int::limb_bits - shift); + result.data()[i] |= result.data()[i-offset-1] << (fixed_int::limb_bits - shift); } result.data()[i] = result.data()[i+offset] >> shift; - result.data()[i] |= fill << (packed_cpp_int::limb_bits - shift); + result.data()[i] |= fill << (fixed_int::limb_bits - shift); --i; for(; i >= 0; --i) result.data()[i] = fill; @@ -955,37 +978,37 @@ inline void right_shift(packed_cpp_int& result, boost::uintmax_t s for(; i >= 0; --i) result.data()[i] = fill; } - result.data()[0] &= packed_cpp_int::upper_limb_mask; + result.data()[0] &= fixed_int::upper_limb_mask; } template -inline typename enable_if, void>::type convert_to(R* result, const packed_cpp_int& backend) +inline typename enable_if, void>::type convert_to(R* result, const fixed_int& backend) { - unsigned shift = (packed_cpp_int::limb_count - 1) * packed_cpp_int::limb_bits; + unsigned shift = (fixed_int::limb_count - 1) * fixed_int::limb_bits; *result = 0; - for(unsigned i = 0; i < packed_cpp_int::limb_count; ++i) + for(unsigned i = 0; i < fixed_int::limb_count; ++i) { *result += static_cast(backend.data()[i]) << shift; - shift -= packed_cpp_int::limb_bits; + shift -= fixed_int::limb_bits; } } template -inline typename enable_if, void>::type convert_to(R* result, const packed_cpp_int& backend) +inline typename enable_if, void>::type convert_to(R* result, const fixed_int& backend) { - unsigned shift = (packed_cpp_int::limb_count - 1) * packed_cpp_int::limb_bits; + unsigned shift = (fixed_int::limb_count - 1) * fixed_int::limb_bits; *result = 0; - for(unsigned i = 0; i < packed_cpp_int::limb_count; ++i) + for(unsigned i = 0; i < fixed_int::limb_count; ++i) { *result += static_cast(std::ldexp(static_cast(backend.data()[i]), shift)); - shift -= packed_cpp_int::limb_bits; + shift -= fixed_int::limb_bits; } } template -inline bool is_zero(const packed_cpp_int& val) +inline bool is_zero(const fixed_int& val) { - for(typename packed_cpp_int::data_type::size_type i = 0; i < packed_cpp_int::limb_count; ++i) + for(typename fixed_int::data_type::size_type i = 0; i < fixed_int::limb_count; ++i) { if(val.data()[i]) return false; @@ -993,28 +1016,28 @@ inline bool is_zero(const packed_cpp_int& val) return true; } template -inline int get_sign(const packed_cpp_int& val) +inline int get_sign(const fixed_int& val) { return is_zero(val) ? 0 : 1; } template -inline int get_sign(const packed_cpp_int& val) +inline int get_sign(const fixed_int& val) { - return is_zero(val) ? 0 : val.data()[0] & packed_cpp_int::sign_bit_mask ? -1 : 1; + return is_zero(val) ? 0 : val.data()[0] & fixed_int::sign_bit_mask ? -1 : 1; } template -struct number_category > : public mpl::int_{}; +struct number_category > : public mpl::int_{}; -typedef mp_number > mp_uint64_t; -typedef mp_number > mp_uint128_t; -typedef mp_number > mp_uint256_t; -typedef mp_number > mp_uint512_t; +typedef mp_number > mp_uint64_t; +typedef mp_number > mp_uint128_t; +typedef mp_number > mp_uint256_t; +typedef mp_number > mp_uint512_t; -typedef mp_number > mp_int64_t; -typedef mp_number > mp_int128_t; -typedef mp_number > mp_int256_t; -typedef mp_number > mp_int512_t; +typedef mp_number > mp_int64_t; +typedef mp_number > mp_int128_t; +typedef mp_number > mp_int256_t; +typedef mp_number > mp_int512_t; }} // namespaces @@ -1022,16 +1045,16 @@ typedef mp_number > mp_int512_t; namespace std{ template -class numeric_limits > > +class numeric_limits > > { - typedef boost::multiprecision::mp_number > number_type; + typedef boost::multiprecision::mp_number > number_type; struct initializer { initializer() { - (std::numeric_limits > >::min)(); - (std::numeric_limits > >::max)(); + (std::numeric_limits > >::min)(); + (std::numeric_limits > >::max)(); } void do_nothing()const{} }; @@ -1096,8 +1119,8 @@ public: }; template -typename numeric_limits > >::initializer const - numeric_limits > >::init; +typename numeric_limits > >::initializer const + numeric_limits > >::init; } #endif diff --git a/performance/performance_test.cpp b/performance/performance_test.cpp index 1d53c89c..1eecb5d7 100644 --- a/performance/performance_test.cpp +++ b/performance/performance_test.cpp @@ -12,14 +12,14 @@ #if !defined(TEST_MPF) && !defined(TEST_MPZ) && \ !defined(TEST_CPP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPQ) \ && !defined(TEST_TOMMATH) && !defined(TEST_TOMMATH_BOOST_RATIONAL) && !defined(TEST_MPZ_BOOST_RATIONAL)\ - && !defined(TEST_PACKED_INT) + && !defined(TEST_FIXED_INT) # define TEST_MPF # define TEST_MPZ # define TEST_MPFR # define TEST_CPP_FLOAT # define TEST_MPQ # define TEST_TOMMATH -# define TEST_PACKED_INT +# define TEST_FIXED_INT #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -44,8 +44,8 @@ #include #include #endif -#if defined(TEST_PACKED_INT) -#include +#if defined(TEST_FIXED_INT) +#include #endif #include @@ -347,12 +347,12 @@ int main() test("tommath_int", 512); test("tommath_int", 1024); #endif -#ifdef TEST_PACKED_INT +#ifdef TEST_FIXED_INT test("mp_int64_t", 64); test("mp_int128_t", 128); test("mp_int256_t", 256); test("mp_int512_t", 512); - test > >("mp_int1024_t", 1024); + test > >("mp_int1024_t", 1024); #endif #ifdef TEST_CPP_FLOAT test("cpp_float", 50); diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index c06d453b..c74c7f1f 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -132,15 +132,15 @@ run test_arithmetic.cpp : # command line : # input files : # requirements - TEST_PACKED_INT1 - : test_arithmetic_packed_int1 ; + TEST_FIXED_INT1 + : test_arithmetic_fixed_int1 ; run test_arithmetic.cpp : # command line : # input files : # requirements - TEST_PACKED_INT2 - : test_arithmetic_packed_int2 ; + TEST_FIXED_INT2 + : test_arithmetic_fixed_int2 ; run test_numeric_limits.cpp : # command line @@ -585,17 +585,17 @@ run test_int_io.cpp : # command line : # input files : # requirements - TEST_PACKED_INT1 - : test_int_io_packed_int1 ; + TEST_FIXED_INT1 + : test_int_io_fixed_int1 ; run test_int_io.cpp : # command line : # input files : # requirements - TEST_PACKED_INT2 - : test_int_io_packed_int2 ; + TEST_FIXED_INT2 + : test_int_io_fixed_int2 ; -run packed_int_test.cpp gmp +run fixed_int_test.cpp gmp : # command line : # input files : # requirements diff --git a/test/packed_int_test.cpp b/test/packed_int_test.cpp index f895c142..02bed7cb 100644 --- a/test/packed_int_test.cpp +++ b/test/packed_int_test.cpp @@ -4,7 +4,7 @@ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_ // -// Compare arithmetic results using packed_cpp_int to GMP results. +// Compare arithmetic results using fixed_int to GMP results. // #ifdef _MSC_VER @@ -12,7 +12,7 @@ #endif #include -#include +#include #include #include #include "test.hpp" @@ -54,7 +54,7 @@ T generate_random(unsigned bits_wanted) int main() { using namespace boost::multiprecision; - typedef mp_number > packed_type; + typedef mp_number > packed_type; unsigned last_error_count = 0; for(int i = 0; i < 1000; ++i) { diff --git a/test/test_arithmetic.cpp b/test/test_arithmetic.cpp index 5339152a..e4fd33ae 100644 --- a/test/test_arithmetic.cpp +++ b/test/test_arithmetic.cpp @@ -13,7 +13,7 @@ #if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && \ !defined(TEST_CPP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) \ && !defined(TEST_TOMMATH) && !defined(TEST_TOMMATH_BOOST_RATIONAL) && !defined(TEST_MPZ_BOOST_RATIONAL)\ - && !defined(TEST_PACKED_INT1) && !defined(TEST_PACKED_INT2) + && !defined(TEST_FIXED_INT1) && !defined(TEST_FIXED_INT2) # define TEST_MPF_50 # define TEST_MPF # define TEST_BACKEND @@ -23,8 +23,8 @@ # define TEST_CPP_FLOAT # define TEST_MPQ # define TEST_TOMMATH -# define TEST_PACKED_INT1 -# define TEST_PACKED_INT2 +# define TEST_FIXED_INT1 +# define TEST_FIXED_INT2 #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -52,8 +52,8 @@ #include #include #endif -#if defined(TEST_PACKED_INT1) || defined(TEST_PACKED_INT2) -#include +#if defined(TEST_FIXED_INT1) || defined(TEST_FIXED_INT2) +#include #endif #if defined(TEST_TOMMATH_BOOST_RATIONAL) || defined(TEST_MPZ_BOOST_RATIONAL) #include @@ -999,13 +999,13 @@ int main() #ifdef TEST_MPZ_BOOST_RATIONAL test >(); #endif -#ifdef TEST_PACKED_INT1 +#ifdef TEST_FIXED_INT1 test(); test(); test(); - test > >(); + test > >(); #endif -#ifdef TEST_PACKED_INT2 +#ifdef TEST_FIXED_INT2 // // Can't test 64-bit signed ints - they don't have enough bits // to interoperate with uint64_t without loss: @@ -1013,7 +1013,7 @@ int main() //test(); test(); test(); - test > >(); + test > >(); #endif return boost::report_errors(); } diff --git a/test/test_int_io.cpp b/test/test_int_io.cpp index ffd7d063..d091521d 100644 --- a/test/test_int_io.cpp +++ b/test/test_int_io.cpp @@ -9,11 +9,11 @@ # define _SCL_SECURE_NO_WARNINGS #endif -#if !defined(TEST_MPZ) && !defined(TEST_TOMMATH) && !defined(TEST_PACKED_INT1) && !defined(TEST_PACKED_INT2) +#if !defined(TEST_MPZ) && !defined(TEST_TOMMATH) && !defined(TEST_FIXED_INT1) && !defined(TEST_FIXED_INT2) # define TEST_TOMMATH # define TEST_MPZ -# define TEST_PACKED_INT1 -# define TEST_PACKED_INT2 +# define TEST_FIXED_INT1 +# define TEST_FIXED_INT2 #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -30,8 +30,8 @@ #if defined(TEST_TOMMATH) #include #endif -#if defined(TEST_PACKED_INT1) || defined(TEST_PACKED_INT2) -#include +#if defined(TEST_FIXED_INT1) || defined(TEST_FIXED_INT2) +#include #endif #include @@ -123,19 +123,19 @@ int main() #ifdef TEST_TOMMATH test_round_trip(); #endif -#ifdef TEST_PACKED_INT1 +#ifdef TEST_FIXED_INT1 test_round_trip(); test_round_trip(); test_round_trip(); - test_round_trip > >(); - test_round_trip > >(); + test_round_trip > >(); + test_round_trip > >(); #endif -#ifdef TEST_PACKED_INT2 +#ifdef TEST_FIXED_INT2 test_round_trip(); test_round_trip(); test_round_trip(); - test_round_trip > >(); - test_round_trip > >(); + test_round_trip > >(); + test_round_trip > >(); #endif return boost::report_errors(); }