From 40123e7170713d33945b472dfeaf73d485af67e7 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Tue, 22 Nov 2011 09:51:58 +0000 Subject: [PATCH] Change number formatting when std::ios_base::fixed is set to print the requested number of digits, padding with zeros as required. [SVN r75602] --- include/boost/multiprecision/cpp_float.hpp | 8 ++++++ include/boost/multiprecision/gmp.hpp | 27 ++++++++++++------ include/boost/multiprecision/mpfr.hpp | 32 +++++++++++++--------- 3 files changed, 45 insertions(+), 22 deletions(-) diff --git a/include/boost/multiprecision/cpp_float.hpp b/include/boost/multiprecision/cpp_float.hpp index 51b0eb95..41ad3005 100644 --- a/include/boost/multiprecision/cpp_float.hpp +++ b/include/boost/multiprecision/cpp_float.hpp @@ -1755,6 +1755,14 @@ std::string cpp_float::str(std::streamsize number_of_digits, std::ios_ str.append(1, 'e'); str.append(boost::lexical_cast(my_exp)); } + if(showpoint || scientific) + { + std::streamsize chars = str.size() - 1; + BOOST_ASSERT(str.find('.') != std::string::npos); // there must be a decimal point!! + chars = number_of_digits - chars; + if(chars > 0) + str.append(chars, '0'); + } if(isneg()) str.insert(0, 1, '-'); else if(shopos) diff --git a/include/boost/multiprecision/gmp.hpp b/include/boost/multiprecision/gmp.hpp index 7faa4b58..150782cb 100644 --- a/include/boost/multiprecision/gmp.hpp +++ b/include/boost/multiprecision/gmp.hpp @@ -173,17 +173,14 @@ struct gmp_float_imp void (*free_func_ptr) (void *, size_t); const char* ps = mpf_get_str (0, &e, 10, static_cast(digits), m_data); std::ptrdiff_t sl = std::strlen(ps); + if(ps && *ps == '-') + --sl; // number of digits excluding sign. + result = ps; if(sl == 0) { result = scientific ? "0.0e0" : showpoint ? "0.0" : "0"; - if(showpos) - result.insert(0, 1, '+'); - return "0"; } - if(*ps == '-') - --sl; // number of digits excluding sign. - result = ps; - if(fixed || (!scientific && (e > -4) && (e <= std::numeric_limits::digits10 + 2))) + else if(fixed || (!scientific && (e > -4) && (e <= std::numeric_limits::digits10 + 2))) { if(1 + e >= sl) { @@ -215,8 +212,20 @@ struct gmp_float_imp if(e) result += "e" + lexical_cast(e); } - if(shopos && (str[0] != '-')) - str.insert(0, 1, '+'); + if(showpoint || scientific) + { + // Pad out end with zeros as required to give required precision. + std::streamsize chars = result.size() - 1; + BOOST_ASSERT(result.find('.') != std::string::npos); // there must be a decimal point!! + BOOST_ASSERT(result.size()); // Better not be a null string by this point!! + if(result[0] == '-') + --chars; + chars = digits - chars; + if(chars > 0) + result.append(static_cast(chars), '0'); + } + if(showpos && (result[0] != '-')) + result.insert(0, 1, '+'); mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr); (*free_func_ptr)((void*)ps, std::strlen(ps) + 1); return result; diff --git a/include/boost/multiprecision/mpfr.hpp b/include/boost/multiprecision/mpfr.hpp index 22c2f3f9..2fbae2c8 100644 --- a/include/boost/multiprecision/mpfr.hpp +++ b/include/boost/multiprecision/mpfr.hpp @@ -168,21 +168,15 @@ struct mpfr_float_imp char* ps = mpfr_get_str (0, &e, 10, static_cast(digits), m_data, GMP_RNDN); std::ptrdiff_t sl = std::strlen(ps); int chars = sl; - if(sl == 0) - { - result = scientific ? "0.0e0" : showpoint ? "0.0" : "0"; - if(showpos) - result.insert(0, 1, '+'); - return "0"; - } - while(ps[chars-1] == '0') + while(chars && (ps[chars-1] == '0')) --chars; ps[chars] = 0; - if(*ps == '-') + if(chars && (*ps == '-')) --chars; // number of digits excluding sign. if(chars == 0) - return scientific ? "0.0e0" : showpoint ? "0.0" : "0"; - result = ps; + result = "0"; + else + result = ps; if(fixed || (!scientific && (e > -4) && (e <= std::numeric_limits::digits10 + 2))) { if(e >= chars) @@ -215,8 +209,20 @@ struct mpfr_float_imp if(e) result += "e" + lexical_cast(e); } - if(shopos && (str[0] != '-')) - str.insert(0, 1, '+'); + if(showpoint || scientific) + { + // Pad out end with zeros as required to give required precision. + std::streamsize chars = result.size() - 1; + BOOST_ASSERT(result.find('.') != std::string::npos); // there must be a decimal point!! + BOOST_ASSERT(result.size()); // Better not be a null string by this point!! + if(result[0] == '-') + --chars; + chars = digits - chars; + if(chars > 0) + result.append(static_cast(chars), '0'); + } + if(showpos && (result[0] != '-')) + result.insert(0, 1, '+'); mpfr_free_str(ps); return result; }