Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r76639 - in sandbox/big_number: boost/multiprecision boost/multiprecision/detail libs/multiprecision/performance libs/multiprecision/test
From: john_at_[hidden]
Date: 2012-01-22 14:12:39


Author: johnmaddock
Date: 2012-01-22 14:12:37 EST (Sun, 22 Jan 2012)
New Revision: 76639
URL: http://svn.boost.org/trac/boost/changeset/76639

Log:
Improve performance of fixed_int divide and string conversion.
Add mixed integer ops to fixed_int.
Improve fixed_int test cases.
Add improved default forwarding functions that preserve arithmetic type arguments.
Fix some operator overloads.
Update performance tests.
Added:
   sandbox/big_number/libs/multiprecision/performance/Jamfile.v2 (contents, props changed)
Text files modified:
   sandbox/big_number/boost/multiprecision/detail/default_ops.hpp | 33 +++
   sandbox/big_number/boost/multiprecision/detail/mp_number_base.hpp | 4
   sandbox/big_number/boost/multiprecision/fixed_int.hpp | 352 +++++++++++++++++++++++++++++++++++----
   sandbox/big_number/libs/multiprecision/performance/performance_test.cpp | 75 ++++++++
   sandbox/big_number/libs/multiprecision/performance/sf_performance.cpp | 119 +++++++++++++
   sandbox/big_number/libs/multiprecision/test/Jamfile.v2 | 2
   sandbox/big_number/libs/multiprecision/test/test_fixed_int.cpp | 37 ++++
   7 files changed, 574 insertions(+), 48 deletions(-)

Modified: sandbox/big_number/boost/multiprecision/detail/default_ops.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/default_ops.hpp (original)
+++ sandbox/big_number/boost/multiprecision/detail/default_ops.hpp 2012-01-22 14:12:37 EST (Sun, 22 Jan 2012)
@@ -131,6 +131,12 @@
       add(t, v);
    }
 }
+template<class T, class U>
+inline typename disable_if<is_same<T, U> >::type add(T& t, const U& a, const T& b)
+{
+ return add(t, b, a);
+}
+
 template <class T, class U, class V>
 inline void subtract(T& t, const U& u, const V& v)
 {
@@ -147,6 +153,13 @@
       subtract(t, v);
    }
 }
+template <class T, class U>
+inline typename disable_if<is_same<T, U> >::type subtract(T& t, const U& a, const T& b)
+{
+ subtract(t, b, a);
+ t.negate();
+}
+
 template <class T, class U, class V>
 inline void multiply(T& t, const U& u, const V& v)
 {
@@ -160,6 +173,11 @@
       multiply(t, v);
    }
 }
+template <class T, class U>
+inline typename disable_if<is_same<T, U> >::type multiply(T& t, const U& a, const T& b)
+{
+ multiply(t, b, a);
+}
 template <class T, class U, class V>
 inline void divide(T& t, const U& u, const V& v)
 {
@@ -207,6 +225,11 @@
       bitwise_and(t, v);
    }
 }
+template <class T, class U>
+inline typename disable_if<is_same<T, U> >::type bitwise_and(T& t, const U& a, const T& b)
+{
+ bitwise_and(t, b, a);
+}
 
 template <class T, class U, class V>
 inline void bitwise_or(T& t, const U& u, const V& v)
@@ -221,6 +244,11 @@
       bitwise_or(t, v);
    }
 }
+template <class T, class U>
+inline typename disable_if<is_same<T, U> >::type bitwise_or(T& t, const U& a, const T& b)
+{
+ bitwise_or(t, b, a);
+}
 
 template <class T, class U, class V>
 inline void bitwise_xor(T& t, const U& u, const V& v)
@@ -235,6 +263,11 @@
       bitwise_xor(t, v);
    }
 }
+template <class T, class U>
+inline typename disable_if<is_same<T, U> >::type bitwise_xor(T& t, const U& a, const T& b)
+{
+ bitwise_xor(t, b, a);
+}
 
 template <class T>
 inline void increment(T& val)

Modified: sandbox/big_number/boost/multiprecision/detail/mp_number_base.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/mp_number_base.hpp (original)
+++ sandbox/big_number/boost/multiprecision/detail/mp_number_base.hpp 2012-01-22 14:12:37 EST (Sun, 22 Jan 2012)
@@ -591,7 +591,7 @@
    return detail::mp_exp<detail::subtract_immediates, mp_number<B>, mp_number<B> >(b, a.left_ref());
 }
 template <class B, class V>
-inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::subtract_immediates, mp_number<B>, V > >::type
+inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::subtract_immediates, V, mp_number<B> > >::type
    operator + (const detail::mp_exp<detail::negate, mp_number<B> >& a, const V& b)
 {
    return detail::mp_exp<detail::subtract_immediates, V, mp_number<B> >(b, a.left_ref());
@@ -686,7 +686,7 @@
 inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::negate, detail::mp_exp<detail::add_immediates, mp_number<B>, V > > >::type
    operator - (const detail::mp_exp<detail::negate, mp_number<B> >& a, const V& b)
 {
- return detail::mp_exp<detail::add_immediates, V, mp_number<B> >(b, a.left_ref());
+ return detail::mp_exp<detail::negate, detail::mp_exp<detail::add_immediates, mp_number<B>, V > >(detail::mp_exp<detail::add_immediates, mp_number<B>, V >(a.left_ref(), b));
 }
 template <class V, class B>
 inline typename enable_if<is_arithmetic<V>, detail::mp_exp<detail::add_immediates, V, mp_number<B> > >::type

Modified: sandbox/big_number/boost/multiprecision/fixed_int.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/fixed_int.hpp (original)
+++ sandbox/big_number/boost/multiprecision/fixed_int.hpp 2012-01-22 14:12:37 EST (Sun, 22 Jan 2012)
@@ -307,8 +307,7 @@
          result.assign(Bits / 3 + 1, '0');
          int pos = result.size() - 1;
          fixed_int t(*this);
- fixed_int ten, r;
- ten = limb_type(max_block_10);
+ fixed_int r;
          bool neg = false;
          if(Signed && (t.data()[0] & sign_bit_mask))
          {
@@ -324,7 +323,7 @@
             while(get_sign(t) != 0)
             {
                fixed_int t2;
- divide_unsigned_helper(t2, t, ten, r);
+ divide_unsigned_helper(t2, t, max_block_10, r);
                t = t2;
                limb_type v = r.data()[limb_count - 1];
                for(unsigned i = 0; i < digits_per_block_10; ++i)
@@ -440,7 +439,7 @@
       + 1uLL + static_cast<double_limb_type>(~o);
    result.data()[fixed_int<Bits, Signed>::limb_count - 1] = static_cast<limb_type>(carry);
    carry >>= fixed_int<Bits, Signed>::limb_bits;
- for(int i = static_cast<int>(fixed_int<Bits, Signed>::limb_count) - 2; i >= 0; --i)
+ for(int i = static_cast<int>(fixed_int<Bits, Signed>::limb_count) - 2; (carry != 1) && (i >= 0); --i)
    {
       carry += static_cast<double_limb_type>(result.data()[i]) + 0xFFFFFFFF;
       result.data()[i] = static_cast<limb_type>(carry);
@@ -684,7 +683,7 @@
     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
+ from the remainder r. One wrinkle 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
@@ -699,47 +698,57 @@
 
    using default_ops::subtract;
 
-
- if (is_zero(y))
+ if(&result == &r)
    {
- volatile int i = 0;
- i /= i;
+ fixed_int<Bits, Signed> rem;
+ divide_unsigned_helper(result, x, y, rem);
+ r = rem;
       return;
    }
 
- if (is_zero(x))
+ //
+ // Find the most significant words of numerator and denominator.
+ //
+ limb_type y_order = 0;
+ while((y.data()[y_order] == 0) && (y_order < fixed_int<Bits, Signed>::limb_count))
+ ++y_order;
+
+ if(y_order >= fixed_int<Bits, Signed>::limb_count - 1)
    {
- r = y;
- result = x;
+ //
+ // Only a single non-zero limb in the denominator, in this case
+ // we can use a specialized divide-by-single-limb routine which is
+ // much faster. This also handles division by zero:
+ //
+ divide_unsigned_helper(result, x, y.data()[y_order], r);
       return;
    }
 
- if(&result == &r)
+ limb_type r_order = 0;
+ while((x.data()[r_order] == 0) && (r_order < fixed_int<Bits, Signed>::limb_count))
+ ++r_order;
+ if(r_order == fixed_int<Bits, Signed>::limb_count)
    {
- fixed_int<Bits, Signed> rem;
- divide_unsigned_helper(result, x, y, rem);
- r = rem;
+ // x is zero, so is the result:
+ r = y;
+ result = x;
       return;
    }
 
    r = x;
    result = static_cast<limb_type>(0u);
- if(x.compare(y) < 0)
- {
- return; // We already have the answer: zero.
- }
-
    //
- // Find the most significant words of numerator and denominator.
- // Note that this code can't run past the end of the array because
- // we know already that neither are all zero:
+ // Check if the remainder is already less than the divisor, if so
+ // we already have the result. Note we try and avoid a full compare
+ // if we can:
    //
- limb_type r_order = 0;
- while(r.data()[r_order] == 0)
- ++r_order;
- limb_type y_order = 0;
- while(y.data()[y_order] == 0)
- ++y_order;
+ if(r_order >= y_order)
+ {
+ if((r_order > y_order) || (r.compare(y) < 0))
+ {
+ return;
+ }
+ }
 
    fixed_int<Bits, Signed> t;
    bool r_neg = false;
@@ -765,8 +774,6 @@
       return;
    }
 
- //fixed_int<Bits, Signed> last_r;
- //bool last_neg;
    do
    {
       //
@@ -778,8 +785,6 @@
       // Calculate our best guess for how many times y divides into r:
       //
       limb_type guess;
- //last_r = r;
- //last_neg = r_neg;
       if((r.data()[r_order] <= y.data()[y_order]) && (r_order < fixed_int<Bits, Signed>::limb_count - 1))
       {
          double_limb_type a, b, v;
@@ -794,15 +799,19 @@
             ++r_order;
          }
       }
+ else if(r_order == fixed_int<Bits, Signed>::limb_count - 1)
+ {
+ guess = r.data()[r_order] / y.data()[y_order];
+ }
       else
       {
          double_limb_type a, b, v;
- a = (r_order < fixed_int<Bits, Signed>::limb_count - 1) ? (static_cast<double_limb_type>(r.data()[r_order]) << fixed_int<Bits, Signed>::limb_bits) | r.data()[r_order + 1] : r.data()[r_order];
+ a = (static_cast<double_limb_type>(r.data()[r_order]) << fixed_int<Bits, Signed>::limb_bits) | r.data()[r_order + 1];
          b = (y_order < fixed_int<Bits, Signed>::limb_count - 1) ? (static_cast<double_limb_type>(y.data()[y_order]) << fixed_int<Bits, Signed>::limb_bits) | y.data()[y_order + 1] : (static_cast<double_limb_type>(y.data()[y_order]) << fixed_int<Bits, Signed>::limb_bits);
          v = a / b;
          guess = static_cast<limb_type>(v);
- //guess = r.data()[r_order] / y.data()[y_order];
       }
+ BOOST_ASSERT(guess); // If the guess ever gets to zero we go on forever....
       //
       // Update result:
       //
@@ -842,7 +851,7 @@
          carry >>= fixed_int<Bits, Signed>::limb_bits;
       }
       t.data()[0] &= fixed_int<Bits, Signed>::upper_limb_mask;
- //
+ //
       // Update r:
       //
       subtract(r, t);
@@ -852,7 +861,9 @@
          r_neg = !r_neg;
       }
    }
- while(r.compare(y) > 0);
+ // Termination condition is really just a check that r > y, but with two common
+ // short-circuit cases handled first:
+ while((r_order < y_order) || (r.data()[r_order] > y.data()[y_order]) || (r.compare(y) > 0));
 
    //
    // We now just have to normalise the result:
@@ -869,6 +880,110 @@
 }
 
 template <unsigned Bits, bool Signed>
+void divide_unsigned_helper(fixed_int<Bits, Signed>& result, const fixed_int<Bits, Signed>& x, limb_type y, fixed_int<Bits, Signed>& r)
+{
+ if((&result == &x) || (&r == &x))
+ {
+ fixed_int<Bits, Signed> t(x);
+ divide_unsigned_helper(result, t, y, r);
+ return;
+ }
+
+ if(&result == &r)
+ {
+ fixed_int<Bits, Signed> rem;
+ divide_unsigned_helper(result, x, y, rem);
+ r = rem;
+ return;
+ }
+
+ // As above, but simplified for integer divisor:
+
+ using default_ops::subtract;
+
+ if(y == 0)
+ {
+ BOOST_THROW_EXCEPTION(std::runtime_error("Integer Division by zero."));
+ }
+ //
+ // Find the most significant word of numerator.
+ //
+ limb_type r_order = 0;
+ while((x.data()[r_order] == 0) && (r_order < fixed_int<Bits, Signed>::limb_count))
+ ++r_order;
+
+ //
+ // Set remainder and result to their initial values:
+ //
+ r = x;
+ result = static_cast<limb_type>(0u);
+
+ if(r_order == fixed_int<Bits, Signed>::limb_count)
+ {
+ // All the limbs in x are zero, so is the result:
+ return;
+ }
+ //
+ // check for x < y, try to do this without actually having to
+ // do a full comparison:
+ //
+ if((r_order == fixed_int<Bits, Signed>::limb_count - 1) && (r.data()[r_order] < y))
+ {
+ return;
+ }
+
+ //
+ // See if we can short-circuit long division, and use basic arithmetic instead:
+ //
+ if(r_order == fixed_int<Bits, Signed>::limb_count - 1)
+ {
+ result = r.data()[fixed_int<Bits, Signed>::limb_count - 1] / y;
+ r = x.data()[fixed_int<Bits, Signed>::limb_count - 1] % y;
+ return;
+ }
+ else if(r_order == static_cast<int>(fixed_int<Bits, Signed>::limb_count) - 2)
+ {
+ double_limb_type a;
+ a = (static_cast<double_limb_type>(r.data()[r_order]) << fixed_int<Bits, Signed>::limb_bits) | r.data()[r_order + 1];
+ result = a / y;
+ r = a % y;
+ return;
+ }
+
+ do
+ {
+ //
+ // Update r_order, this can't run past the end as r must be non-zero at this point:
+ //
+ while(r.data()[r_order] == 0)
+ ++r_order;
+ //
+ // Calculate our best guess for how many times y divides into r:
+ //
+ if((r.data()[r_order] < y) && (r_order < fixed_int<Bits, Signed>::limb_count - 1))
+ {
+ double_limb_type a, b;
+ a = (static_cast<double_limb_type>(r.data()[r_order]) << fixed_int<Bits, Signed>::limb_bits) | r.data()[r_order + 1];
+ b = a % y;
+ r.data()[r_order] = 0;
+ ++r_order;
+ r.data()[r_order] = static_cast<limb_type>(b);
+ result.data()[r_order] = static_cast<limb_type>(a / y);
+ }
+ else
+ {
+ result.data()[r_order] = r.data()[r_order] / y;
+ r.data()[r_order] %= y;
+ }
+ }
+ // Termination condition is really just a check that r > y, but with two common
+ // short-circuit cases handled first:
+ while((r_order < fixed_int<Bits, Signed>::limb_count - 1) || (r.data()[r_order] > y));
+
+ BOOST_ASSERT(r.compare(y) < 0); // remainder must be less than the divisor or our code has failed
+}
+
+template <unsigned Bits, bool Signed>
 inline void divide(fixed_int<Bits, Signed>& result, const fixed_int<Bits, Signed>& a, const fixed_int<Bits, Signed>& b)
 {
    fixed_int<Bits, Signed> r;
@@ -902,6 +1017,52 @@
    }
 }
 template <unsigned Bits, bool Signed>
+inline void divide(fixed_int<Bits, Signed>& result, const fixed_int<Bits, Signed>& a, limb_type& b)
+{
+ fixed_int<Bits, Signed> r;
+ if(Signed && (a.data()[0] & fixed_int<Bits, Signed>::sign_bit_mask))
+ {
+ fixed_int<Bits, Signed> t(a);
+ t.negate();
+ divide_unsigned_helper(result, t, b, r);
+ result.negate();
+ }
+ else
+ {
+ divide_unsigned_helper(result, a, b, r);
+ }
+}
+template <unsigned Bits, bool Signed>
+inline void divide(fixed_int<Bits, Signed>& result, const fixed_int<Bits, Signed>& a, signed_limb_type& b)
+{
+ fixed_int<Bits, Signed> r;
+ if(Signed && (a.data()[0] & fixed_int<Bits, Signed>::sign_bit_mask))
+ {
+ if(b < 0)
+ {
+ fixed_int<Bits, Signed> t(a);
+ t.negate();
+ divide_unsigned_helper(result, t, static_cast<limb_type>(-b), r);
+ }
+ else
+ {
+ fixed_int<Bits, Signed> t(a);
+ t.negate();
+ divide_unsigned_helper(result, t, b, r);
+ result.negate();
+ }
+ }
+ else if(b < 0)
+ {
+ divide_unsigned_helper(result, a, static_cast<limb_type>(-b), r);
+ result.negate();
+ }
+ else
+ {
+ divide_unsigned_helper(result, a, static_cast<limb_type>(b), r);
+ }
+}
+template <unsigned Bits, bool Signed>
 inline void divide(fixed_int<Bits, Signed>& result, const fixed_int<Bits, Signed>& b)
 {
    // There is no in place divide:
@@ -909,6 +1070,20 @@
    divide(result, a, b);
 }
 template <unsigned Bits, bool Signed>
+inline void divide(fixed_int<Bits, Signed>& result, limb_type b)
+{
+ // There is no in place divide:
+ fixed_int<Bits, Signed> a(result);
+ divide(result, a, b);
+}
+template <unsigned Bits, bool Signed>
+inline void divide(fixed_int<Bits, Signed>& result, signed_limb_type b)
+{
+ // There is no in place divide:
+ fixed_int<Bits, Signed> a(result);
+ divide(result, a, b);
+}
+template <unsigned Bits, bool Signed>
 inline void modulus(fixed_int<Bits, Signed>& result, const fixed_int<Bits, Signed>& a, const fixed_int<Bits, Signed>& b)
 {
    fixed_int<Bits, Signed> r;
@@ -942,12 +1117,72 @@
    }
 }
 template <unsigned Bits, bool Signed>
+inline void modulus(fixed_int<Bits, Signed>& result, const fixed_int<Bits, Signed>& a, limb_type b)
+{
+ fixed_int<Bits, Signed> r;
+ if(Signed && (a.data()[0] & fixed_int<Bits, Signed>::sign_bit_mask))
+ {
+ fixed_int<Bits, Signed> t(a);
+ t.negate();
+ divide_unsigned_helper(r, t, b, result);
+ result.negate();
+ }
+ else
+ {
+ divide_unsigned_helper(r, a, b, result);
+ }
+}
+template <unsigned Bits, bool Signed>
+inline void modulus(fixed_int<Bits, Signed>& result, const fixed_int<Bits, Signed>& a, signed_limb_type b)
+{
+ fixed_int<Bits, Signed> r;
+ if(Signed && (a.data()[0] & fixed_int<Bits, Signed>::sign_bit_mask))
+ {
+ if(b < 0)
+ {
+ fixed_int<Bits, Signed> t1(a);
+ t1.negate();
+ divide_unsigned_helper(r, t1, static_cast<limb_type>(-b), result);
+ result.negate();
+ }
+ else
+ {
+ fixed_int<Bits, Signed> t(a);
+ t.negate();
+ divide_unsigned_helper(r, t, b, result);
+ result.negate();
+ }
+ }
+ else if(b < 0)
+ {
+ divide_unsigned_helper(r, a, static_cast<limb_type>(-b), result);
+ }
+ else
+ {
+ divide_unsigned_helper(r, a, static_cast<limb_type>(b), result);
+ }
+}
+template <unsigned Bits, bool Signed>
 inline void modulus(fixed_int<Bits, Signed>& result, const fixed_int<Bits, Signed>& b)
 {
    // There is no in place divide:
    fixed_int<Bits, Signed> a(result);
    modulus(result, a, b);
 }
+template <unsigned Bits, bool Signed>
+inline void modulus(fixed_int<Bits, Signed>& result, limb_type b)
+{
+ // There is no in place divide:
+ fixed_int<Bits, Signed> a(result);
+ modulus(result, a, b);
+}
+template <unsigned Bits, bool Signed>
+inline void modulus(fixed_int<Bits, Signed>& result, signed_limb_type b)
+{
+ // There is no in place divide:
+ fixed_int<Bits, Signed> a(result);
+ modulus(result, a, b);
+}
 
 template <unsigned Bits, bool Signed>
 inline void bitwise_and(fixed_int<Bits, Signed>& result, const fixed_int<Bits, Signed>& o)
@@ -956,12 +1191,40 @@
       result.data()[i] &= o.data()[i];
 }
 template <unsigned Bits, bool Signed>
+inline void bitwise_and(fixed_int<Bits, Signed>& result, limb_type o)
+{
+ result.data()[fixed_int<Bits, Signed>::limb_count - 1] &= o;
+ for(typename fixed_int<Bits, Signed>::data_type::size_type i = 0; i < fixed_int<Bits, Signed>::limb_count - 1; ++i)
+ result.data()[i] = 0;
+}
+template <unsigned Bits, bool Signed>
+inline void bitwise_and(fixed_int<Bits, Signed>& result, signed_limb_type o)
+{
+ result.data()[fixed_int<Bits, Signed>::limb_count - 1] &= o;
+ limb_type mask = o < 0 ? fixed_int<Bits, Signed>::max_limb_value : 0;
+ for(typename fixed_int<Bits, Signed>::data_type::size_type i = 0; i < fixed_int<Bits, Signed>::limb_count - 1; ++i)
+ result.data()[i] &= mask;
+}
+template <unsigned Bits, bool Signed>
 inline void bitwise_or(fixed_int<Bits, Signed>& result, const fixed_int<Bits, Signed>& o)
 {
    for(typename fixed_int<Bits, Signed>::data_type::size_type i = 0; i < fixed_int<Bits, Signed>::limb_count; ++i)
       result.data()[i] |= o.data()[i];
 }
 template <unsigned Bits, bool Signed>
+inline void bitwise_or(fixed_int<Bits, Signed>& result, limb_type o)
+{
+ result.data()[fixed_int<Bits, Signed>::limb_count - 1] |= o;
+}
+template <unsigned Bits, bool Signed>
+inline void bitwise_or(fixed_int<Bits, Signed>& result, signed_limb_type o)
+{
+ result.data()[fixed_int<Bits, Signed>::limb_count - 1] |= o;
+ limb_type mask = o < 0 ? fixed_int<Bits, Signed>::max_limb_value : 0;
+ for(typename fixed_int<Bits, Signed>::data_type::size_type i = 0; i < fixed_int<Bits, Signed>::limb_count - 1; ++i)
+ result.data()[i] |= mask;
+}
+template <unsigned Bits, bool Signed>
 inline void bitwise_xor(fixed_int<Bits, Signed>& result, const fixed_int<Bits, Signed>& o)
 {
    for(typename fixed_int<Bits, Signed>::data_type::size_type i = 0; i < fixed_int<Bits, Signed>::limb_count; ++i)
@@ -969,6 +1232,19 @@
    result.data()[0] &= fixed_int<Bits, Signed>::upper_limb_mask;
 }
 template <unsigned Bits, bool Signed>
+inline void bitwise_xor(fixed_int<Bits, Signed>& result, limb_type o)
+{
+ result.data()[fixed_int<Bits, Signed>::limb_count - 1] ^= o;
+}
+template <unsigned Bits, bool Signed>
+inline void bitwise_xor(fixed_int<Bits, Signed>& result, signed_limb_type o)
+{
+ result.data()[fixed_int<Bits, Signed>::limb_count - 1] ^= o;
+ limb_type mask = o < 0 ? fixed_int<Bits, Signed>::max_limb_value : 0;
+ for(typename fixed_int<Bits, Signed>::data_type::size_type i = 0; i < fixed_int<Bits, Signed>::limb_count - 1; ++i)
+ result.data()[i] ^= mask;
+}
+template <unsigned Bits, bool Signed>
 inline void complement(fixed_int<Bits, Signed>& result, const fixed_int<Bits, Signed>& o)
 {
    for(typename fixed_int<Bits, Signed>::data_type::size_type i = 0; i < fixed_int<Bits, Signed>::limb_count; ++i)

Added: sandbox/big_number/libs/multiprecision/performance/Jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/big_number/libs/multiprecision/performance/Jamfile.v2 2012-01-22 14:12:37 EST (Sun, 22 Jan 2012)
@@ -0,0 +1,106 @@
+# copyright John Maddock 2012
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt.
+
+import modules ;
+import path ;
+
+local ntl-path = [ modules.peek : NTL_PATH ] ;
+local gmp_path = [ modules.peek : GMP_PATH ] ;
+local mpfr_path = [ modules.peek : MPFR_PATH ] ;
+local tommath_path = [ modules.peek : TOMMATH_PATH ] ;
+
+project : requirements
+ <include>$(gmp_path)
+ <include>$(gmp_path)/mpfr
+ <include>$(gmp_path)/gmpfrxx
+ <include>$(mpfr_path)
+ <include>$(tommath_path)
+ <include>../../..
+ <search>$(gmp_path)
+ <search>$(mpfr_path)
+ <search>$(mpfr_path)/build.vc10/lib/Win32/Debug
+ <search>$(tommath_path)
+ <link>static
+ <define>BOOST_ALL_NO_LIB
+ <debug-symbols>off
+ ;
+
+
+lib gmp ;
+lib mpfr ;
+
+if $(tommath_path)
+{
+ TOMMATH = [ GLOB $(tommath_path) : *.c ] ;
+}
+else
+{
+ lib tommath ;
+ TOMMATH = tommath ;
+}
+
+exe performance_test : performance_test.cpp /boost/system//boost_system
+ : release
+ [ check-target-builds ../config//has_gmp : <define>TEST_MPF <define>TEST_MPZ <source>gmp : ]
+ [ check-target-builds ../config//has_mpfr : <define>TEST_MPFR <source>mpfr : ]
+ [ check-target-builds ../config//has_tommath : <define>TEST_TOMMATH <source>$(TOMMATH) : ]
+ <define>TEST_CPP_FLOAT
+ <define>TEST_FIXED_INT
+ ;
+
+exe sf_performance : sf_performance.cpp
+ : release
+ [ check-target-builds ../config//has_gmp : <define>TEST_MPF <define>TEST_MPZ <source>gmp : ]
+ [ check-target-builds ../config//has_mpfr : <define>TEST_MPFR <source>mpfr : ]
+ <define>TEST_CPP_FLOAT
+ <toolset>msvc:<cxxflags>-bigobj
+ ;
+
+obj obj_linpack_benchmark_mpfr : linpack-benchmark.cpp
+ : release
+ [ check-target-builds ../config//has_mpfr : : <build>no ]
+ <define>TEST_MPFR_50
+ ;
+
+obj obj_linpack_benchmark_mpf : linpack-benchmark.cpp
+ : release
+ [ check-target-builds ../config//has_gmp : : <build>no ]
+ <define>TEST_MPF_50
+ ;
+
+obj obj_linpack_benchmark_cpp_float : linpack-benchmark.cpp
+ : release
+ <define>TEST_CPP_FLOAT
+ ;
+
+obj obj_linpack_benchmark_double : linpack-benchmark.cpp
+ : release
+ ;
+
+obj obj_f2c : f2c.c : release ;
+
+exe linpack_benchmark_mpfr : obj_linpack_benchmark_mpfr mpfr obj_f2c
+ : release
+ [ check-target-builds ../config//has_mpfr : : <build>no ]
+ <define>TEST_MPFR_50
+ ;
+
+exe linpack_benchmark_mpf : obj_linpack_benchmark_mpf gmp obj_f2c
+ : release
+ [ check-target-builds ../config//has_gmp : : <build>no ]
+ <define>TEST_MPF_50
+ ;
+
+exe linpack_benchmark_cpp_float : obj_linpack_benchmark_cpp_float obj_f2c
+ : release
+ <define>TEST_CPP_FLOAT
+ ;
+
+exe linpack_benchmark_double : obj_linpack_benchmark_double obj_f2c
+ : release
+ ;
+
+install . : performance_test sf_performance linpack_benchmark_double linpack_benchmark_cpp_float linpack_benchmark_mpf linpack_benchmark_mpfr ;
+

Modified: sandbox/big_number/libs/multiprecision/performance/performance_test.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/performance/performance_test.cpp (original)
+++ sandbox/big_number/libs/multiprecision/performance/performance_test.cpp 2012-01-22 14:12:37 EST (Sun, 22 Jan 2012)
@@ -145,6 +145,16 @@
       }
       return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
    }
+ double test_multiply_int()
+ {
+ stopwatch<boost::chrono::high_resolution_clock> w;
+ for(unsigned i = 0; i < 1000; ++i)
+ {
+ for(unsigned i = 0; i < b.size(); ++i)
+ a[i] = b[i] * 3;
+ }
+ return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
+ }
    double test_divide()
    {
       stopwatch<boost::chrono::high_resolution_clock> w;
@@ -155,6 +165,16 @@
       }
       return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
    }
+ double test_divide_int()
+ {
+ stopwatch<boost::chrono::high_resolution_clock> w;
+ for(unsigned i = 0; i < 1000; ++i)
+ {
+ for(unsigned i = 0; i < b.size(); ++i)
+ a[i] = b[i] / 3;
+ }
+ return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
+ }
    double test_str()
    {
       stopwatch<boost::chrono::high_resolution_clock> w;
@@ -163,7 +183,7 @@
       return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
    }
    //
- // The following tests only work for ineteger types:
+ // The following tests only work for integer types:
    //
    double test_mod()
    {
@@ -175,6 +195,16 @@
       }
       return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
    }
+ double test_mod_int()
+ {
+ stopwatch<boost::chrono::high_resolution_clock> w;
+ for(unsigned i = 0; i < 1000; ++i)
+ {
+ for(unsigned i = 0; i < b.size(); ++i)
+ a[i] = b[i] % 254;
+ }
+ return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
+ }
    double test_or()
    {
       stopwatch<boost::chrono::high_resolution_clock> w;
@@ -185,6 +215,16 @@
       }
       return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
    }
+ double test_or_int()
+ {
+ stopwatch<boost::chrono::high_resolution_clock> w;
+ for(unsigned i = 0; i < 1000; ++i)
+ {
+ for(unsigned i = 0; i < b.size(); ++i)
+ a[i] = b[i] | 234;
+ }
+ return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
+ }
    double test_and()
    {
       stopwatch<boost::chrono::high_resolution_clock> w;
@@ -195,6 +235,16 @@
       }
       return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
    }
+ double test_and_int()
+ {
+ stopwatch<boost::chrono::high_resolution_clock> w;
+ for(unsigned i = 0; i < 1000; ++i)
+ {
+ for(unsigned i = 0; i < b.size(); ++i)
+ a[i] = b[i] & 234;
+ }
+ return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
+ }
    double test_xor()
    {
       stopwatch<boost::chrono::high_resolution_clock> w;
@@ -205,6 +255,16 @@
       }
       return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
    }
+ double test_xor_int()
+ {
+ stopwatch<boost::chrono::high_resolution_clock> w;
+ for(unsigned i = 0; i < 1000; ++i)
+ {
+ for(unsigned i = 0; i < b.size(); ++i)
+ a[i] = b[i] ^ 234;
+ }
+ return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
+ }
    double test_complement()
    {
       stopwatch<boost::chrono::high_resolution_clock> w;
@@ -380,6 +440,11 @@
    //report_result(cat, type, "~", precision, t.test_complement());
    report_result(cat, type, "<<", precision, t.test_left_shift());
    report_result(cat, type, ">>", precision, t.test_right_shift());
+ // integer ops:
+ report_result(cat, type, "%(int)", precision, t.test_mod_int());
+ report_result(cat, type, "|(int)", precision, t.test_or_int());
+ report_result(cat, type, "&(int)", precision, t.test_and_int());
+ report_result(cat, type, "^(int)", precision, t.test_xor_int());
 }
 template <class Number, int N, class U>
 void test_int_ops(tester<Number, N>& t, const char* type, unsigned precision, const U&)
@@ -403,12 +468,14 @@
    //
    report_result(cat, type, "+", precision, t.test_add());
    report_result(cat, type, "-", precision, t.test_subtract());
- report_result(cat, type, "+(int)", precision, t.test_add_int());
- report_result(cat, type, "-(int)", precision, t.test_subtract_int());
    report_result(cat, type, "*", precision, t.test_multiply());
    report_result(cat, type, "/", precision, t.test_divide());
    report_result(cat, type, "str", precision, t.test_str());
-
+ // integer ops:
+ report_result(cat, type, "+(int)", precision, t.test_add_int());
+ report_result(cat, type, "-(int)", precision, t.test_subtract_int());
+ report_result(cat, type, "*(int)", precision, t.test_multiply_int());
+ report_result(cat, type, "/(int)", precision, t.test_divide_int());
    test_int_ops(t, type, precision, typename boost::multiprecision::number_category<Number>::type());
 }
 

Modified: sandbox/big_number/libs/multiprecision/performance/sf_performance.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/performance/sf_performance.cpp (original)
+++ sandbox/big_number/libs/multiprecision/performance/sf_performance.cpp 2012-01-22 14:12:37 EST (Sun, 22 Jan 2012)
@@ -6,14 +6,31 @@
 #define BOOST_CHRONO_HEADER_ONLY
 #define BOOST_MATH_MAX_ROOT_ITERATION_POLICY 500
 
+#if !defined(TEST_MPFR) && !defined(TEST_MP_REAL) && !defined(TEST_MPF)
+# define TEST_MPFR
+# define TEST_MPF
+# define TEST_MPF
+# define TEST_CPP_FLOAT
+# define TEST_MPFR_CLASS
+#endif
+
+#ifdef TEST_MPFR
 #include <boost/math/bindings/mpfr.hpp>
-#include <boost/math/bindings/mpreal.hpp>
 #include <boost/multiprecision/mpfr.hpp>
+#endif
+#ifdef TEST_MP_REAL
+#include <boost/math/bindings/mpreal.hpp>
+#endif
+#ifdef TEST_MPF
 #include <boost/multiprecision/gmp.hpp>
+#endif
+#ifdef TEST_CPP_FLOAT
 #include <boost/multiprecision/cpp_float.hpp>
+#endif
 #include <boost/math/special_functions/bessel.hpp>
 #include <boost/math/tools/rational.hpp>
 #include <boost/math/distributions/non_central_t.hpp>
+#include <libs/math/test/table_type.hpp>
 #include <boost/chrono.hpp>
 #include <boost/array.hpp>
 
@@ -149,29 +166,40 @@
 
    static const unsigned a[] = {
       2, 3, 4, 5, 6, 7, 8 };
+#ifdef TEST_MPFR
    boost::multiprecision::mpfr_float_50 result, x(2);
    allocation_count = 0;
    result = (((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0];
    std::cout << allocation_count << std::endl;
+#endif
+#ifdef TEST_MPFR_CLASS
    mpfr_class r, x2(2);
    allocation_count = 0;
    r = (((((a[6] * x2 + a[5]) * x2 + a[4]) * x2 + a[3]) * x2 + a[2]) * x2 + a[1]) * x2 + a[0];
    std::cout << allocation_count << std::endl;
+#endif
+#ifdef TEST_MPREAL
    mpfr::mpreal r2, x3(2);
    allocation_count = 0;
    r2 = (((((a[6] * x3 + a[5]) * x3 + a[4]) * x3 + a[3]) * x3 + a[2]) * x3 + a[1]) * x3 + a[0];
    std::cout << allocation_count << std::endl;
+#endif
 
    allocation_count = 0;
+#ifdef TEST_MPFR
    result = boost::math::tools::evaluate_polynomial(a, x);
    std::cout << allocation_count << std::endl;
    allocation_count = 0;
+#endif
+#ifdef TEST_MPFR_CLASS
    r = boost::math::tools::evaluate_polynomial(a, x2);
    std::cout << allocation_count << std::endl;
    allocation_count = 0;
+#endif
+#ifdef TEST_MPREAL
    r2 = boost::math::tools::evaluate_polynomial(a, x3);
    std::cout << allocation_count << std::endl;
-
+#endif
 
    boost::chrono::duration<double> time;
    stopwatch<boost::chrono::high_resolution_clock> c;
@@ -179,216 +207,301 @@
    // 50 digits first:
    //
    std::cout << "Testing Bessel Functions....." << std::endl;
+#if defined(TEST_MPFR) || defined(TEST_MPFR_CLASS)
    mpfr_set_default_prec(50 * 1000L / 301L);
+#endif
+#ifdef TEST_MPREAL
    mpfr::mpreal::set_default_prec(50 * 1000L / 301L);
+#endif
+#ifdef TEST_MPFR
    c.reset();
    test_bessel<boost::multiprecision::mpfr_float_50>();
    time = c.elapsed();
    std::cout << "Time for mpfr_float_50 = " << time << std::endl;
    std::cout << "Total allocations for mpfr_float_50 = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
+#ifdef TEST_MPF
+ c.reset();
    test_bessel<boost::multiprecision::mpf_float_50>();
    time = c.elapsed();
    std::cout << "Time for mpf_float_50 = " << time << std::endl;
    std::cout << "Total allocations for mpf_float_50 = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
+#ifdef TEST_CPP_FLOAT
+ c.reset();
    test_bessel<boost::multiprecision::cpp_float_50>();
    time = c.elapsed();
    std::cout << "Time for cpp_float_50 = " << time << std::endl;
    std::cout << "Total allocations for cpp_float_50 = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
+#ifdef TEST_MPFR_CLASS
    c.reset();
    test_bessel<mpfr_class>();
    time = c.elapsed();
    std::cout << "Time for mpfr_class (50 digits) = " << time << std::endl;
    std::cout << "Total allocations for mpfr_class (50 digits) = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
+#ifdef TEST_MP_REAL
    c.reset();
    test_bessel<mpfr::mpreal>();
    time = c.elapsed();
    std::cout << "Time for mpreal (50 digits) = " << time << std::endl;
    std::cout << "Total allocations for mpreal (50 digits) = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
    //
    // Then 100 digits:
    //
+#if defined(TEST_MPFR) || defined(TEST_MPFR_CLASS)
    mpfr_set_default_prec(100 * 1000L / 301L);
+#endif
+#ifdef TEST_MPREAL
    mpfr::mpreal::set_default_prec(100 * 1000L / 301L);
+#endif
+#ifdef TEST_MPFR
    c.reset();
    test_bessel<boost::multiprecision::mpfr_float_100>();
    time = c.elapsed();
    std::cout << "Time for mpfr_float_100 = " << time << std::endl;
    std::cout << "Total allocations for mpfr_float_50 = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
+#ifdef TEST_MPF
    c.reset();
    test_bessel<boost::multiprecision::mpf_float_100>();
    time = c.elapsed();
    std::cout << "Time for mpf_float_100 = " << time << std::endl;
    std::cout << "Total allocations for mpf_float_100 = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
+#ifdef TEST_CPP_FLOAT
    c.reset();
    test_bessel<boost::multiprecision::cpp_float_100>();
    time = c.elapsed();
    std::cout << "Time for cpp_float_100 = " << time << std::endl;
    std::cout << "Total allocations for cpp_float_100 = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
+#ifdef TEST_MPFR_CLASS
    c.reset();
    test_bessel<mpfr_class>();
    time = c.elapsed();
    std::cout << "Time for mpfr_class (100 digits) = " << time << std::endl;
    std::cout << "Total allocations for mpfr_class (100 digits) = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
+#ifdef TEST_MPREAL
    c.reset();
    test_bessel<mpfr::mpreal>();
    time = c.elapsed();
    std::cout << "Time for mpreal (100 digits) = " << time << std::endl;
    std::cout << "Total allocations for mpreal (100 digits) = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
 
    //
    // 50 digits first:
    //
    c.reset();
    std::cout << "Testing Polynomial Evaluation....." << std::endl;
+#if defined(TEST_MPFR) || defined(TEST_MPFR_CLASS)
    mpfr_set_default_prec(50 * 1000L / 301L);
+#endif
+#ifdef TEST_MPREAL
    mpfr::mpreal::set_default_prec(50 * 1000L / 301L);
+#endif
+#ifdef TEST_MPFR
    c.reset();
    test_polynomial<boost::multiprecision::mpfr_float_50>();
    time = c.elapsed();
    std::cout << "Time for mpfr_float_50 = " << time << std::endl;
    std::cout << "Total allocations for mpfr_float_50 = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
+#ifdef TEST_MPF
    c.reset();
    test_polynomial<boost::multiprecision::mpf_float_50>();
    time = c.elapsed();
    std::cout << "Time for mpf_float_50 = " << time << std::endl;
    std::cout << "Total allocations for mpf_float_50 = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
+#ifdef TEST_CPP_FLOAT
    c.reset();
    test_polynomial<boost::multiprecision::cpp_float_50>();
    time = c.elapsed();
    std::cout << "Time for cpp_float_50 = " << time << std::endl;
    std::cout << "Total allocations for cpp_float_50 = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
+#ifdef TEST_MPFR_CLASS
    c.reset();
    test_polynomial<mpfr_class>();
    time = c.elapsed();
    std::cout << "Time for mpfr_class (50 digits) = " << time << std::endl;
    std::cout << "Total allocations for mpfr_class (50 digits) = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
+#ifdef TEST_MPREAL
    c.reset();
    test_polynomial<mpfr::mpreal>();
    time = c.elapsed();
    std::cout << "Time for mpreal (50 digits) = " << time << std::endl;
    std::cout << "Total allocations for mpreal (50 digits = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
    //
    // Then 100 digits:
    //
+#ifdef TEST_MPFR_CLASS
    mpfr_set_default_prec(100 * 1000L / 301L);
+#endif
+#ifdef TEST_MPREAL
    mpfr::mpreal::set_default_prec(100 * 1000L / 301L);
+#endif
+#ifdef TEST_MPFR
    c.reset();
    test_polynomial<boost::multiprecision::mpfr_float_100>();
    time = c.elapsed();
    std::cout << "Time for mpfr_float_100 = " << time << std::endl;
    std::cout << "Total allocations for mpfr_float_100 = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
+#ifdef TEST_MPF
    c.reset();
    test_polynomial<boost::multiprecision::mpf_float_100>();
    time = c.elapsed();
    std::cout << "Time for mpf_float_100 = " << time << std::endl;
    std::cout << "Total allocations for mpf_float_100 = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
+#ifdef TEST_CPP_FLOAT
    c.reset();
    test_polynomial<boost::multiprecision::cpp_float_100>();
    time = c.elapsed();
    std::cout << "Time for cpp_float_100 = " << time << std::endl;
    std::cout << "Total allocations for cpp_float_100 = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
+#ifdef TEST_MPFR_CLASS
    c.reset();
    test_polynomial<mpfr_class>();
    time = c.elapsed();
    std::cout << "Time for mpfr_class (100 digits) = " << time << std::endl;
    std::cout << "Total allocations for mpfr_class (100 digits) = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
+#ifdef TEST_MPREAL
    c.reset();
    test_polynomial<mpfr::mpreal>();
    time = c.elapsed();
    std::cout << "Time for mpreal (100 digits) = " << time << std::endl;
    std::cout << "Total allocations for mpreal (100 digits) = " << allocation_count << std::endl;
    allocation_count = 0;
-
+#endif
    //
    // 50 digits first:
    //
    c.reset();
    std::cout << "Testing Non-Central T....." << std::endl;
+#ifdef TEST_MPFR_CLASS
    mpfr_set_default_prec(50 * 1000L / 301L);
+#endif
+#ifdef TEST_MPREAL
    mpfr::mpreal::set_default_prec(50 * 1000L / 301L);
+#endif
+#ifdef TEST_MPFR
    c.reset();
    test_nct<boost::multiprecision::mpfr_float_50>();
    time = c.elapsed();
    std::cout << "Time for mpfr_float_50 = " << time << std::endl;
    std::cout << "Total allocations for mpfr_float_50 = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
+#ifdef TEST_MPF
    c.reset();
    test_nct<boost::multiprecision::mpf_float_50>();
    time = c.elapsed();
    std::cout << "Time for mpf_float_50 = " << time << std::endl;
    std::cout << "Total allocations for mpf_float_50 = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
+#ifdef TEST_CPP_FLOAT
    c.reset();
    test_nct<boost::multiprecision::cpp_float_50>();
    time = c.elapsed();
    std::cout << "Time for cpp_float_50 = " << time << std::endl;
    std::cout << "Total allocations for cpp_float_50 = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
+#ifdef TEST_MPFR_CLASS
    c.reset();
    test_nct<mpfr_class>();
    time = c.elapsed();
    std::cout << "Time for mpfr_class (50 digits) = " << time << std::endl;
    std::cout << "Total allocations for mpfr_class (50 digits) = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
+#ifdef TEST_MP_REAL
    c.reset();
    test_nct<mpfr::mpreal>();
    time = c.elapsed();
    std::cout << "Time for mpreal (50 digits) = " << time << std::endl;
    std::cout << "Total allocations for mpreal (50 digits) = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
    //
    // Then 100 digits:
    //
+#ifdef TEST_MPFR_CLASS
    mpfr_set_default_prec(100 * 1000L / 301L);
+#endif
+#ifdef TEST_MPREAL
    mpfr::mpreal::set_default_prec(100 * 1000L / 301L);
+#endif
+#ifdef TEST_MPFR
    c.reset();
    test_nct<boost::multiprecision::mpfr_float_100>();
    time = c.elapsed();
    std::cout << "Time for mpfr_float_100 = " << time << std::endl;
    std::cout << "Total allocations for mpfr_float_100 = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
+#ifdef TEST_MPF
    c.reset();
    test_nct<boost::multiprecision::mpf_float_100>();
    time = c.elapsed();
    std::cout << "Time for mpf_float_100 = " << time << std::endl;
    std::cout << "Total allocations for mpf_float_100 = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
+#ifdef TEST_CPP_FLOAT
    c.reset();
    test_nct<boost::multiprecision::cpp_float_100>();
    time = c.elapsed();
    std::cout << "Time for cpp_float_100 = " << time << std::endl;
    std::cout << "Total allocations for cpp_float_100 = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
+#ifdef TEST_MPFR_CLASS
    c.reset();
    test_nct<mpfr_class>();
    time = c.elapsed();
    std::cout << "Time for mpfr_class (100 digits) = " << time << std::endl;
    std::cout << "Total allocations for mpfr_class (100 digits) = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
+#ifdef TEST_MPREAL
    c.reset();
    test_nct<mpfr::mpreal>();
    time = c.elapsed();
    std::cout << "Time for mpreal (100 digits) = " << time << std::endl;
    std::cout << "Total allocations for mpreal (100 digits) = " << allocation_count << std::endl;
    allocation_count = 0;
+#endif
 }
 

Modified: sandbox/big_number/libs/multiprecision/test/Jamfile.v2
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/Jamfile.v2 (original)
+++ sandbox/big_number/libs/multiprecision/test/Jamfile.v2 2012-01-22 14:12:37 EST (Sun, 22 Jan 2012)
@@ -1,4 +1,4 @@
-# copyright John Maddock 2008
+# copyright John Maddock 2011
 # Distributed under the Boost Software License, Version 1.0.
 # (See accompanying file LICENSE_1_0.txt or copy at
 # http://www.boost.org/LICENSE_1_0.txt.

Modified: sandbox/big_number/libs/multiprecision/test/test_fixed_int.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/test_fixed_int.cpp (original)
+++ sandbox/big_number/libs/multiprecision/test/test_fixed_int.cpp 2012-01-22 14:12:37 EST (Sun, 22 Jan 2012)
@@ -63,6 +63,8 @@
       mpz_int c = generate_random<mpz_int>(256);
       mpz_int d = generate_random<mpz_int>(32);
 
+ int si = d.convert_to<int>();
+
       packed_type a1 = a.str();
       packed_type b1 = b.str();
       packed_type c1 = c.str();
@@ -77,11 +79,46 @@
       BOOST_CHECK_EQUAL(mpz_int(mpz_int(-a)+b).str(), packed_type(packed_type(-a1) + b1).str());
       BOOST_CHECK_EQUAL(mpz_int(mpz_int(-a)-b).str(), packed_type(packed_type(-a1) - b1).str());
       BOOST_CHECK_EQUAL(mpz_int(c * d).str(), packed_type(c1 * d1).str());
+ BOOST_CHECK_EQUAL(mpz_int(c * -d).str(), packed_type(c1 * -d1).str());
+ BOOST_CHECK_EQUAL(mpz_int(-c * d).str(), packed_type(-c1 * d1).str());
       BOOST_CHECK_EQUAL(mpz_int(b * c).str(), packed_type(b1 * c1).str());
       BOOST_CHECK_EQUAL(mpz_int(a / b).str(), packed_type(a1 / b1).str());
+ BOOST_CHECK_EQUAL(mpz_int(a / -b).str(), packed_type(a1 / -b1).str());
+ BOOST_CHECK_EQUAL(mpz_int(-a / b).str(), packed_type(-a1 / b1).str());
       BOOST_CHECK_EQUAL(mpz_int(a / d).str(), packed_type(a1 / d1).str());
       BOOST_CHECK_EQUAL(mpz_int(a % b).str(), packed_type(a1 % b1).str());
+ BOOST_CHECK_EQUAL(mpz_int(a % -b).str(), packed_type(a1 % -b1).str());
+ BOOST_CHECK_EQUAL(mpz_int(-a % b).str(), packed_type(-a1 % b1).str());
       BOOST_CHECK_EQUAL(mpz_int(a % d).str(), packed_type(a1 % d1).str());
+ // bitwise ops:
+ BOOST_CHECK_EQUAL(mpz_int(a|b).str(), packed_type(a1 | b1).str());
+ BOOST_CHECK_EQUAL(mpz_int(a&b).str(), packed_type(a1 & b1).str());
+ BOOST_CHECK_EQUAL(mpz_int(a^b).str(), packed_type(a1 ^ b1).str());
+ // Now check operations involving integers:
+ BOOST_CHECK_EQUAL(mpz_int(a + si).str(), packed_type(a1 + si).str());
+ BOOST_CHECK_EQUAL(mpz_int(a + -si).str(), packed_type(a1 + -si).str());
+ BOOST_CHECK_EQUAL(mpz_int(-a + si).str(), packed_type(-a1 + si).str());
+ BOOST_CHECK_EQUAL(mpz_int(si + a).str(), packed_type(si + a1).str());
+ BOOST_CHECK_EQUAL(mpz_int(a - si).str(), packed_type(a1 - si).str());
+ BOOST_CHECK_EQUAL(mpz_int(a - -si).str(), packed_type(a1 - -si).str());
+ BOOST_CHECK_EQUAL(mpz_int(-a - si).str(), packed_type(-a1 - si).str());
+ BOOST_CHECK_EQUAL(mpz_int(si - a).str(), packed_type(si - a1).str());
+ BOOST_CHECK_EQUAL(mpz_int(b * si).str(), packed_type(b1 * si).str());
+ BOOST_CHECK_EQUAL(mpz_int(b * -si).str(), packed_type(b1 * -si).str());
+ BOOST_CHECK_EQUAL(mpz_int(-b * si).str(), packed_type(-b1 * si).str());
+ BOOST_CHECK_EQUAL(mpz_int(si * b).str(), packed_type(si * b1).str());
+ BOOST_CHECK_EQUAL(mpz_int(a / si).str(), packed_type(a1 / si).str());
+ BOOST_CHECK_EQUAL(mpz_int(a / -si).str(), packed_type(a1 / -si).str());
+ BOOST_CHECK_EQUAL(mpz_int(-a / si).str(), packed_type(-a1 / si).str());
+ BOOST_CHECK_EQUAL(mpz_int(a % si).str(), packed_type(a1 % si).str());
+ BOOST_CHECK_EQUAL(mpz_int(a % -si).str(), packed_type(a1 % -si).str());
+ BOOST_CHECK_EQUAL(mpz_int(-a % si).str(), packed_type(-a1 % si).str());
+ BOOST_CHECK_EQUAL(mpz_int(a|si).str(), packed_type(a1 | si).str());
+ BOOST_CHECK_EQUAL(mpz_int(a&si).str(), packed_type(a1 & si).str());
+ BOOST_CHECK_EQUAL(mpz_int(a^si).str(), packed_type(a1 ^ si).str());
+ BOOST_CHECK_EQUAL(mpz_int(si|a).str(), packed_type(si|a1).str());
+ BOOST_CHECK_EQUAL(mpz_int(si&a).str(), packed_type(si&a1).str());
+ BOOST_CHECK_EQUAL(mpz_int(si^a).str(), packed_type(si^a1).str());
 
       if(last_error_count != boost::detail::test_errors())
       {


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk