$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r77473 - in sandbox/big_number: boost/multiprecision libs/multiprecision/test
From: john_at_[hidden]
Date: 2012-03-22 07:54:17
Author: johnmaddock
Date: 2012-03-22 07:54:15 EDT (Thu, 22 Mar 2012)
New Revision: 77473
URL: http://svn.boost.org/trac/boost/changeset/77473
Log:
Fix fixed precision ints to work with non obvious bit counts.
Text files modified: 
   sandbox/big_number/boost/multiprecision/cpp_int.hpp                 |     5 +++++                                   
   sandbox/big_number/libs/multiprecision/test/test_arithmetic.cpp     |     1 +                                       
   sandbox/big_number/libs/multiprecision/test/test_numeric_limits.cpp |    21 ++++++++++++++++++---                   
   3 files changed, 24 insertions(+), 3 deletions(-)
Modified: sandbox/big_number/boost/multiprecision/cpp_int.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/cpp_int.hpp	(original)
+++ sandbox/big_number/boost/multiprecision/cpp_int.hpp	2012-03-22 07:54:15 EDT (Thu, 22 Mar 2012)
@@ -184,6 +184,7 @@
    BOOST_STATIC_CONSTANT(limb_type, sign_bit_mask = 1u << (limb_bits - 1));
    BOOST_STATIC_CONSTANT(unsigned, internal_limb_count = MinBits / limb_bits + (MinBits % limb_bits ? 1 : 0));
    BOOST_STATIC_CONSTANT(bool, variable = false);
+   BOOST_STATIC_CONSTANT(limb_type, upper_limb_mask = MinBits % limb_bits ? (limb_type(1) << (MinBits % limb_bits)) -1 : (~limb_type(0)));
    BOOST_STATIC_ASSERT_MSG(internal_limb_count >= 2, "A fixed precision integer type must have at least 2 limbs");
 
 private:
@@ -216,7 +217,9 @@
    void normalize()
    {
       limb_pointer p = limbs();
+      p[internal_limb_count-1] &= upper_limb_mask;
       while((m_limbs-1) && !p[m_limbs - 1])--m_limbs;
+      if((m_limbs == 1) && (!*p)) m_sign = false; // zero is always unsigned
    }
 
    cpp_int_base() : m_limbs(1), m_sign(false)
@@ -280,6 +283,7 @@
    BOOST_STATIC_CONSTANT(limb_type, sign_bit_mask = 1u << (limb_bits - 1));
    BOOST_STATIC_CONSTANT(unsigned, internal_limb_count = MinBits / limb_bits + (MinBits % limb_bits ? 1 : 0));
    BOOST_STATIC_CONSTANT(bool, variable = false);
+   BOOST_STATIC_CONSTANT(limb_type, upper_limb_mask = MinBits % limb_bits ? (limb_type(1) << (MinBits % limb_bits)) -1 : (~limb_type(0)));
    BOOST_STATIC_ASSERT_MSG(internal_limb_count >= 2, "A fixed precision integer type must have at least 2 limbs");
 
 private:
@@ -302,6 +306,7 @@
    void normalize()
    {
       limb_pointer p = limbs();
+      p[internal_limb_count-1] &= upper_limb_mask;
       while((m_limbs-1) && !p[m_limbs - 1])--m_limbs;
    }
 
Modified: sandbox/big_number/libs/multiprecision/test/test_arithmetic.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/test_arithmetic.cpp	(original)
+++ sandbox/big_number/libs/multiprecision/test/test_arithmetic.cpp	2012-03-22 07:54:15 EDT (Thu, 22 Mar 2012)
@@ -1059,6 +1059,7 @@
    test<boost::multiprecision::mp_uint512_t >();
    test<boost::multiprecision::cpp_rational>();
    test<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<>, false> >();
+   test<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<500, true, void> > >();
 #endif
 #ifdef TEST_CPP_INT_BR
    test<boost::multiprecision::cpp_rational>();
Modified: sandbox/big_number/libs/multiprecision/test/test_numeric_limits.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/test_numeric_limits.cpp	(original)
+++ sandbox/big_number/libs/multiprecision/test/test_numeric_limits.cpp	2012-03-22 07:54:15 EDT (Thu, 22 Mar 2012)
@@ -55,7 +55,7 @@
    std::cout << BOOST_STRINGIZE(x) << " = " << std::numeric_limits<Number>::x << std::endl;
 
 template <class Number>
-void test_fp(const boost::mpl::int_<boost::multiprecision::number_kind_floating_point>&)
+void test_specific(const boost::mpl::int_<boost::multiprecision::number_kind_floating_point>&)
 {
    Number minv, maxv;
    minv = (std::numeric_limits<Number>::min)();
@@ -116,8 +116,21 @@
    BOOST_TEST(!(boost::math::isnan)(n));
 }
 
+template <class Number>
+void test_specific(const boost::mpl::int_<boost::multiprecision::number_kind_integer>&)
+{
+   if(std::numeric_limits<Number>::is_modulo)
+   {
+      if(!std::numeric_limits<Number>::is_signed)
+      {
+         BOOST_TEST(1 + (std::numeric_limits<Number>::max)() == 0);
+         BOOST_TEST(--Number(0) == (std::numeric_limits<Number>::max)());
+      }
+   }
+}
+
 template <class Number, class T>
-void test_fp(const T&)
+void test_specific(const T&)
 {
 }
 
@@ -181,7 +194,7 @@
       boost::mpl::int_<500> // not a number type
    >::type fp_test_type;
 
-   test_fp<Number>(fp_test_type());
+   test_specific<Number>(fp_test_type());
 }
 
 
@@ -226,6 +239,8 @@
    test<boost::multiprecision::cpp_int>();
    test<boost::multiprecision::mp_int256_t>();
    test<boost::multiprecision::mp_uint512_t>();
+   test<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<200, false, void> > >();
+   test<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<70, true, void> > >();
 #endif
    return boost::report_errors();
 }