Boost logo

Boost-Commit :

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();
 }


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