Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r79700 - in sandbox/big_number/boost/multiprecision: . detail
From: john_at_[hidden]
Date: 2012-07-23 13:47:45


Author: johnmaddock
Date: 2012-07-23 13:47:44 EDT (Mon, 23 Jul 2012)
New Revision: 79700
URL: http://svn.boost.org/trac/boost/changeset/79700

Log:
Fix Linux x64 failures.
Text files modified:
   sandbox/big_number/boost/multiprecision/cpp_int.hpp | 110 ++++++++++++++++++++++++++++++++++++---
   sandbox/big_number/boost/multiprecision/detail/cpp_int_core.hpp | 3 +
   sandbox/big_number/boost/multiprecision/detail/cpp_int_trivial_ops.hpp | 2
   3 files changed, 105 insertions(+), 10 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-07-23 13:47:44 EDT (Mon, 23 Jul 2012)
@@ -425,16 +425,21 @@
    }
 };
 
+template <unsigned N, bool s>
+struct trivial_limb_type_imp
+{
+ typedef double_limb_type type;
+};
+
 template <unsigned N>
-struct trivial_limb_type
+struct trivial_limb_type_imp<N, true>
 {
- typedef typename mpl::if_c<
- N <= sizeof(long long) * CHAR_BIT,
- typename boost::uint_t<N>::least,
- double_limb_type
- >::type type;
+ typedef typename boost::uint_t<N>::least type;
 };
 
+template <unsigned N>
+struct trivial_limb_type : public trivial_limb_type_imp<N, N <= sizeof(long long) * CHAR_BIT> {};
+
 #ifdef BOOST_MSVC
 #pragma warning(push)
 #pragma warning(disable:4244) // loss of data in initialization
@@ -446,10 +451,10 @@
    typedef typename trivial_limb_type<MinBits>::type local_limb_type;
    typedef local_limb_type* limb_pointer;
    typedef const local_limb_type* const_limb_pointer;
-private:
+protected:
    BOOST_STATIC_CONSTANT(unsigned, limb_bits = sizeof(local_limb_type) * CHAR_BIT);
    BOOST_STATIC_CONSTANT(local_limb_type, limb_mask = MinBits < limb_bits ? (local_limb_type(1) << MinBits) -1 : (~local_limb_type(0)));
-
+private:
    local_limb_type m_data;
    bool m_sign;
 
@@ -1058,7 +1063,8 @@
    {
       this->do_swap(o);
    }
- std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags f)const
+private:
+ std::string str(std::ios_base::fmtflags f, const mpl::false_&)const
    {
       std::stringstream ss;
       ss.flags(f);
@@ -1069,6 +1075,92 @@
       result += ss.str();
       return result;
    }
+ std::string str(std::ios_base::fmtflags f, const mpl::true_&)const
+ {
+ // Even though we have only one limb, we can't do IO on it :-(
+ int base = 10;
+ if((f & std::ios_base::oct) == std::ios_base::oct)
+ base = 8;
+ else if((f & std::ios_base::hex) == std::ios_base::hex)
+ base = 16;
+ std::string result;
+
+ unsigned Bits = base_type::limb_bits;
+
+ if(base == 8 || base == 16)
+ {
+ if(this->sign())
+ BOOST_THROW_EXCEPTION(std::runtime_error("Base 8 or 16 printing of negative numbers is not supported."));
+ limb_type shift = base == 8 ? 3 : 4;
+ limb_type mask = static_cast<limb_type>((1u << shift) - 1);
+ typename base_type::local_limb_type v = *this->limbs();
+ result.assign(Bits / shift + (Bits % shift ? 1 : 0), '0');
+ int pos = result.size() - 1;
+ for(unsigned i = 0; i < Bits / shift; ++i)
+ {
+ char c = '0' + static_cast<char>(v & mask);
+ if(c > '9')
+ c += 'A' - '9' - 1;
+ result[pos--] = c;
+ v >>= shift;
+ }
+ if(Bits % shift)
+ {
+ mask = static_cast<limb_type>((1u << (Bits % shift)) - 1);
+ char c = '0' + static_cast<char>(v & mask);
+ if(c > '9')
+ c += 'A' - '9';
+ result[pos] = c;
+ }
+ //
+ // Get rid of leading zeros:
+ //
+ std::string::size_type n = result.find_first_not_of('0');
+ if(!result.empty() && (n == std::string::npos))
+ n = result.size() - 1;
+ result.erase(0, n);
+ if(f & std::ios_base::showbase)
+ {
+ const char* pp = base == 8 ? "0" : "0x";
+ result.insert(0, pp);
+ }
+ }
+ else
+ {
+ result.assign(Bits / 3 + 1, '0');
+ int pos = result.size() - 1;
+ typename base_type::local_limb_type v(*this->limbs());
+ bool neg = false;
+ if(this->sign())
+ {
+ neg = true;
+ }
+ while(v)
+ {
+ result[pos] = (v % 10) + '0';
+ --pos;
+ v /= 10;
+ }
+ unsigned n = result.find_first_not_of('0');
+ result.erase(0, n);
+ if(result.empty())
+ result = "0";
+ if(neg)
+ result.insert(0, 1, '-');
+ else if(f & std::ios_base::showpos)
+ result.insert(0, 1, '+');
+ }
+ return result;
+ }
+public:
+ std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags f)const
+ {
+#ifdef BOOST_MP_NO_DOUBLE_LIMB_TYPE_IO
+ return str(f, mpl::bool_<is_same<typename base_type::local_limb_type, double_limb_type>::value>());
+#else
+ return str(f, mpl::bool_<false>());
+#endif
+ }
    int compare(const cpp_int_backend& o)const BOOST_NOEXCEPT
    {
       if(this->sign() != o.sign())

Modified: sandbox/big_number/boost/multiprecision/detail/cpp_int_core.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/cpp_int_core.hpp (original)
+++ sandbox/big_number/boost/multiprecision/detail/cpp_int_core.hpp 2012-07-23 13:47:44 EDT (Mon, 23 Jul 2012)
@@ -76,6 +76,9 @@
    return values[count];
 }
 
+// Can't do formatted IO on an __int128
+#define BOOST_MP_NO_DOUBLE_LIMB_TYPE_IO
+
 #else
 
 typedef detail::largest_unsigned_type<32>::type limb_type;

Modified: sandbox/big_number/boost/multiprecision/detail/cpp_int_trivial_ops.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/cpp_int_trivial_ops.hpp (original)
+++ sandbox/big_number/boost/multiprecision/detail/cpp_int_trivial_ops.hpp 2012-07-23 13:47:44 EDT (Mon, 23 Jul 2012)
@@ -159,7 +159,7 @@
    }
    a |= b;
    bool isneg = false;
- static const typename cpp_int_backend<MinBits, true, void, true>::local_limb_type mask = static_cast<typename cpp_int_backend<MinBits, true, void, true>::local_limb_type>(1) << (std::numeric_limits<typename cpp_int_backend<MinBits, true, void, true>::local_limb_type>::digits - 1);
+ static const typename cpp_int_backend<MinBits, true, void, true>::local_limb_type mask = static_cast<typename cpp_int_backend<MinBits, true, void, true>::local_limb_type>(1) << (sizeof(typename cpp_int_backend<MinBits, true, void, true>::local_limb_type) * CHAR_BIT - 1);
    if(a & mask)
    {
       a = ~a;


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