Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r75644 - in sandbox/big_number/boost/multiprecision: . detail
From: john_at_[hidden]
Date: 2011-11-24 12:27:19


Author: johnmaddock
Date: 2011-11-24 12:27:17 EST (Thu, 24 Nov 2011)
New Revision: 75644
URL: http://svn.boost.org/trac/boost/changeset/75644

Log:
Mostly fix IO failures.
Text files modified:
   sandbox/big_number/boost/multiprecision/cpp_float.hpp | 79 ++++++++++++++++++++++++---------------
   sandbox/big_number/boost/multiprecision/detail/mp_number_base.hpp | 37 ++++++++++++------
   sandbox/big_number/boost/multiprecision/gmp.hpp | 29 ++++++++++----
   sandbox/big_number/boost/multiprecision/mpfr.hpp | 2 +
   4 files changed, 96 insertions(+), 51 deletions(-)

Modified: sandbox/big_number/boost/multiprecision/cpp_float.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/cpp_float.hpp (original)
+++ sandbox/big_number/boost/multiprecision/cpp_float.hpp 2011-11-24 12:27:17 EST (Thu, 24 Nov 2011)
@@ -1646,7 +1646,9 @@
    if(number_of_digits == 0)
       number_of_digits = cpp_float_max_digits10;
    if(f & std::ios_base::fixed)
+ {
       number_of_digits += my_exp + 1;
+ }
    else if(f & std::ios_base::scientific)
       ++number_of_digits;
    // Determine the number of elements needed to provide the requested digits from cpp_float<Digits10>.
@@ -1667,47 +1669,64 @@
 
       str += ss.str();
    }
-
- // Cut the output to the size of the precision.
- if(str.length() > static_cast<std::string::size_type>(number_of_digits))
+ if(number_of_digits == 0)
    {
- // Get the digit after the last needed digit for rounding
- const boost::uint32_t round = static_cast<boost::uint32_t>(static_cast<boost::uint32_t>(str[static_cast<std::string::size_type>(number_of_digits)]) - static_cast<boost::uint32_t>('0'));
-
- // Truncate the string
- str.erase(static_cast<std::string::size_type>(number_of_digits));
-
- if(round >= static_cast<boost::uint32_t>(5u))
+ // We only get here if the output format is "fixed" and we just need to
+ // round the first digit.
+ str.insert(0, 1, '0');
+ ++number_of_digits;
+ }
+ if(number_of_digits < 0)
+ {
+ str = "0";
+ if(isneg())
+ str.insert(0, 1, '-');
+ boost::multiprecision::detail::format_float_string(str, 0, number_of_digits - my_exp - 1, f);
+ return str;
+ }
+ else
+ {
+ // Cut the output to the size of the precision.
+ if(str.length() > static_cast<std::string::size_type>(number_of_digits))
       {
- std::size_t ix = static_cast<std::size_t>(str.length() - 1u);
+ // Get the digit after the last needed digit for rounding
+ const boost::uint32_t round = static_cast<boost::uint32_t>(static_cast<boost::uint32_t>(str[static_cast<std::string::size_type>(number_of_digits)]) - static_cast<boost::uint32_t>('0'));
 
- // Every trailing 9 must be rounded up
- while(ix && (static_cast<boost::int32_t>(str.at(ix)) - static_cast<boost::int32_t>('0') == static_cast<boost::int32_t>(9)))
- {
- str.at(ix) = static_cast<char>('0');
- --ix;
- }
+ // Truncate the string
+ str.erase(static_cast<std::string::size_type>(number_of_digits));
 
- if(!ix)
+ if(round >= static_cast<boost::uint32_t>(5u))
          {
- // There were nothing but trailing nines.
- if(static_cast<boost::int32_t>(static_cast<boost::int32_t>(str.at(ix)) - static_cast<boost::int32_t>(0x30)) == static_cast<boost::int32_t>(9))
+ std::size_t ix = static_cast<std::size_t>(str.length() - 1u);
+
+ // Every trailing 9 must be rounded up
+ while(ix && (static_cast<boost::int32_t>(str.at(ix)) - static_cast<boost::int32_t>('0') == static_cast<boost::int32_t>(9)))
             {
- // Increment up to the next order and adjust exponent.
- str.at(ix) = static_cast<char>('1');
- ++my_exp;
+ str.at(ix) = static_cast<char>('0');
+ --ix;
+ }
+
+ if(!ix)
+ {
+ // There were nothing but trailing nines.
+ if(static_cast<boost::int32_t>(static_cast<boost::int32_t>(str.at(ix)) - static_cast<boost::int32_t>(0x30)) == static_cast<boost::int32_t>(9))
+ {
+ // Increment up to the next order and adjust exponent.
+ str.at(ix) = static_cast<char>('1');
+ ++my_exp;
+ }
+ else
+ {
+ // Round up this digit.
+ ++str.at(ix);
+ }
             }
             else
             {
- // Round up this digit.
- ++str.at(ix);
+ // Round up the last digit.
+ ++str[ix];
             }
          }
- else
- {
- // Round up the last digit.
- ++str[ix];
- }
       }
    }
    if(isneg())

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 2011-11-24 12:27:17 EST (Thu, 24 Nov 2011)
@@ -9,6 +9,7 @@
 #include <limits>
 #include <boost/utility/enable_if.hpp>
 #include <boost/type_traits/is_convertible.hpp>
+#include <boost/lexical_cast.hpp>
 
 #ifdef BOOST_NO_NOEXCEPT
 #define BOOST_MP_NOEXCEPT
@@ -345,6 +346,14 @@
    static const long value = std::numeric_limits<T>::radix == 10 ? (((std::numeric_limits<T>::digits + 1) * 1000L) / 301L) : std::numeric_limits<T>::digits;
 };
 
+#ifndef BOOST_MP_MIN_EXPONENT_DIGITS
+#ifdef _MSC_VER
+# define BOOST_MP_MIN_EXPONENT_DIGITS 3
+#else
+# define BOOST_MP_MIN_EXPONENT_DIGITS 2
+#endif
+#endif
+
 template <class S>
 void format_float_string(S& str, long long my_exp, std::streamsize digits, std::ios_base::fmtflags f)
 {
@@ -353,7 +362,12 @@
    bool showpoint = (f & std::ios_base::showpoint) == std::ios_base::showpoint;
    bool showpos = (f & std::ios_base::showpos) == std::ios_base::showpos;
 
- if(!fixed && !scientific)
+ bool neg = str.size() && (str[0] == '-');
+
+ if(neg)
+ str.erase(0, 1);
+
+ if(!fixed && !scientific && !showpoint)
    {
       //
       // Suppress trailing zeros:
@@ -372,8 +386,6 @@
       // Pad out the end with zero's if we need to:
       //
       std::streamsize chars = str.size();
- if(chars && str[0] == '-')
- --chars;
       chars = digits - chars;
       if(chars > 0)
       {
@@ -381,14 +393,14 @@
       }
    }
 
- if(fixed || (!scientific && (str.size() < 20) && (my_exp >= -3) && (my_exp < 20)))
+ if(fixed || (!scientific && (my_exp >= -4) && (my_exp < digits)))
    {
       if(1 + my_exp > str.size())
       {
          // Just pad out the end with zeros:
          str.append(static_cast<std::string::size_type>(1 + my_exp - str.size()), '0');
          if(showpoint)
- str.append(".0");
+ str.append(".");
       }
       else if(my_exp + 1 != str.size())
       {
@@ -404,25 +416,26 @@
          }
       }
       else if(showpoint)
- str += ".0";
+ str += ".";
    }
    else
    {
       // Scientific format:
- str.insert(1, 1, '.');
- if(str.size() == 2)
- str.append(1, '0');
+ if(showpoint || (str.size() > 1))
+ str.insert(1, 1, '.');
       str.append(1, 'e');
       S e = boost::lexical_cast<S>(std::abs(my_exp));
- if(e.size() < 3)
- e.insert(0, 3-e.size(), '0');
+ if(e.size() < BOOST_MP_MIN_EXPONENT_DIGITS)
+ e.insert(0, BOOST_MP_MIN_EXPONENT_DIGITS-e.size(), '0');
       if(my_exp < 0)
          e.insert(0, 1, '-');
       else
          e.insert(0, 1, '+');
       str.append(e);
    }
- if(showpos && (str[0] != '-'))
+ if(neg)
+ str.insert(0, 1, '-');
+ else if(showpos)
       str.insert(0, 1, '+');
 }
 

Modified: sandbox/big_number/boost/multiprecision/gmp.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/gmp.hpp (original)
+++ sandbox/big_number/boost/multiprecision/gmp.hpp 2011-11-24 12:27:17 EST (Thu, 24 Nov 2011)
@@ -173,18 +173,29 @@
       void *(*realloc_func_ptr) (void *, size_t, size_t);
       void (*free_func_ptr) (void *, size_t);
       mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr);
- const char* ps = mpf_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data);
- --e; // To match with what our formatter expects.
- if(fixed && e != -1)
+
+ if(mpf_sgn(m_data) == 0)
       {
- // Oops we actually need a different number of digits to what we asked for:
- (*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
- digits += e + 1;
- ps = mpf_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data);
+ e = 0;
+ result = "0";
+ if(fixed)
+ ++digits;
+ }
+ else
+ {
+ const char* ps = mpf_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data);
          --e; // To match with what our formatter expects.
+ if(fixed && e != -1)
+ {
+ // Oops we actually need a different number of digits to what we asked for:
+ (*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
+ digits += e + 1;
+ ps = mpf_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data);
+ --e; // To match with what our formatter expects.
+ }
+ result = ps;
+ (*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
       }
- result = ps;
- (*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
       boost::multiprecision::detail::format_float_string(result, e, digits, f);
       return result;
    }

Modified: sandbox/big_number/boost/multiprecision/mpfr.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/mpfr.hpp (original)
+++ sandbox/big_number/boost/multiprecision/mpfr.hpp 2011-11-24 12:27:17 EST (Thu, 24 Nov 2011)
@@ -170,6 +170,8 @@
       {
          e = 0;
          result = "0";
+ if(fixed)
+ ++digits;
       }
       else
       {


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