Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r73549 - in sandbox/e_float: boost/e_float libs/e_float/src/e_float libs/e_float/src/e_float/efx libs/e_float/src/e_float/mpfr
From: e_float_at_[hidden]
Date: 2011-08-05 11:19:03


Author: christopher_kormanyos
Date: 2011-08-05 11:19:02 EDT (Fri, 05 Aug 2011)
New Revision: 73549
URL: http://svn.boost.org/trac/boost/changeset/73549

Log:
- Implemented proper ostream format for the MPFR back-end.
- Implemented proper interface for Boost.Math for the MPFR back-end.
Text files modified:
   sandbox/e_float/boost/e_float/e_float_base.hpp | 15 ++
   sandbox/e_float/boost/e_float/e_float_efx.hpp | 14 --
   sandbox/e_float/boost/e_float/e_float_mpfr.hpp | 3
   sandbox/e_float/libs/e_float/src/e_float/e_float_base.cpp | 113 ++++++++++++++++++++++
   sandbox/e_float/libs/e_float/src/e_float/efx/e_float_efx.cpp | 126 +-----------------------
   sandbox/e_float/libs/e_float/src/e_float/mpfr/e_float_mpfr.cpp | 201 ++++++++++++++++++++++++++++++++++-----
   6 files changed, 310 insertions(+), 162 deletions(-)

Modified: sandbox/e_float/boost/e_float/e_float_base.hpp
==============================================================================
--- sandbox/e_float/boost/e_float/e_float_base.hpp (original)
+++ sandbox/e_float/boost/e_float/e_float_base.hpp 2011-08-05 11:19:02 EDT (Fri, 05 Aug 2011)
@@ -174,6 +174,21 @@
   protected:
     inline e_float_base();
 
+ static bool char_is_nonzero_predicate(const char& c) { return (c != static_cast<char>('0')); }
+
+ static void wr_string_scientific(std::string& str,
+ const INT64 my_exp,
+ const std::size_t os_precision,
+ const bool my_showpoint,
+ const bool my_uppercase,
+ const bool trim_trailing_zeros = false);
+
+ static void wr_string_fixed(std::string& str,
+ const INT64 my_exp,
+ const std::size_t os_precision,
+ const bool my_showpoint,
+ const bool trim_trailing_zeros = false);
+
   private:
     static bool digits_match_lib_dll_is_ok;
   };

Modified: sandbox/e_float/boost/e_float/e_float_efx.hpp
==============================================================================
--- sandbox/e_float/boost/e_float/e_float_efx.hpp (original)
+++ sandbox/e_float/boost/e_float/e_float_efx.hpp 2011-08-05 11:19:02 EDT (Fri, 05 Aug 2011)
@@ -96,7 +96,6 @@
 
     private:
       static bool data_elem_is_nonzero_predicate(const UINT32& d) { return (d != static_cast<UINT32>(0u)); }
- static bool char_is_nonzero_predicate (const char& c) { return (c != static_cast<char>('0')); }
 
       void from_unsigned_long_long(const unsigned long long u);
       void from_unsigned_long(const unsigned long u);
@@ -163,19 +162,6 @@
       virtual bool rd_string(const char* const s);
 
       static void round_output_string(std::string& str, INT64& my_exp, const std::size_t number_of_digits);
-
- static void wr_string_scientific(std::string& str,
- const INT64 my_exp,
- const std::size_t os_precision,
- const bool my_showpoint,
- const bool my_uppercase,
- const bool trim_trailing_zeros = false);
-
- static void wr_string_fixed(std::string& str,
- const INT64 my_exp,
- const std::size_t os_precision,
- const bool my_showpoint,
- const bool trim_trailing_zeros = false);
     };
   }
 

Modified: sandbox/e_float/boost/e_float/e_float_mpfr.hpp
==============================================================================
--- sandbox/e_float/boost/e_float/e_float_mpfr.hpp (original)
+++ sandbox/e_float/boost/e_float/e_float_mpfr.hpp 2011-08-05 11:19:02 EDT (Fri, 05 Aug 2011)
@@ -78,8 +78,6 @@
 
       static const INT32 ef_digits2 = static_cast<INT32>(((static_cast<INT64>(ef_digits10_tol) * 3322LL) + 500LL) / 1000LL);
 
- private:
-
       ::mpfr_t rop;
 
     public:
@@ -185,6 +183,7 @@
 
     private:
 
+ static void get_raw_digits_from_scientific_string(std::string& str);
       virtual void wr_string(std::string& str, std::ostream& os) const;
       virtual bool rd_string(const char* const s);
 

Modified: sandbox/e_float/libs/e_float/src/e_float/e_float_base.cpp
==============================================================================
--- sandbox/e_float/libs/e_float/src/e_float/e_float_base.cpp (original)
+++ sandbox/e_float/libs/e_float/src/e_float/e_float_base.cpp 2011-08-05 11:19:02 EDT (Fri, 05 Aug 2011)
@@ -86,6 +86,119 @@
   return width_of_e;
 }
 
+void e_float_base::wr_string_scientific(std::string& str,
+ const INT64 my_exp,
+ const std::size_t os_precision,
+ const bool my_showpoint,
+ const bool my_uppercase,
+ const bool trim_trailing_zeros)
+{
+ if(os_precision > static_cast<std::size_t>(str.length() - 1u))
+ {
+ // Zero-extend the string to the given precision if necessary.
+ const std::size_t n_pad = static_cast<std::size_t>(os_precision - (str.length() - 1u));
+
+ str.insert(str.end(), n_pad, static_cast<char>('0'));
+ }
+
+ // Insert the decimal point.
+ str.insert(static_cast<std::size_t>(1u), ".");
+
+ // Remove all trailing zeros if necessary.
+ if(trim_trailing_zeros)
+ {
+ const std::string::const_reverse_iterator rit_non_zero = std::find_if(str.rbegin(), str.rend(), char_is_nonzero_predicate);
+
+ if(rit_non_zero != str.rbegin())
+ {
+ const std::size_t ofs = str.length() - std::distance<std::string::const_reverse_iterator>(str.rbegin(), rit_non_zero);
+ str.erase(str.begin() + ofs, str.end());
+ }
+ }
+
+ // Remove the trailing decimal point if necessary.
+ if((*(str.end() - 1u) == static_cast<char>('.')) && (!my_showpoint))
+ {
+ str.erase(str.end() - 1u, str.end());
+ }
+
+ // Append the exponent in uppercase or lower case, including its sign.
+ const bool b_exp_is_neg = (my_exp < static_cast<INT64>(0));
+ const UINT64 u_exp = static_cast<UINT64>(!b_exp_is_neg ? my_exp : static_cast<INT64>(-my_exp));
+
+ str += (my_uppercase ? "E" : "e");
+ str += (b_exp_is_neg ? "-" : "+");
+ std::string str_exp = Util::lexical_cast(static_cast<INT64>(u_exp));
+
+ // Format the exponent string to have a width that is an even multiple of three.
+ const std::size_t str_exp_len = str_exp.length();
+ const std::size_t str_exp_len_mod3 = static_cast<std::size_t>(str_exp_len % 3u);
+ const std::size_t str_exp_len_pad = ((str_exp_len_mod3 != static_cast<std::size_t>(0u)) ? static_cast<std::size_t>(3u - (str_exp_len % 3u))
+ : static_cast<std::size_t>(0u));
+
+ str += std::string(str_exp_len_pad, static_cast<char>('0'));
+ str += str_exp;
+}
+
+void e_float_base::wr_string_fixed(std::string& str,
+ const INT64 my_exp,
+ const std::size_t os_precision,
+ const bool my_showpoint,
+ const bool trim_trailing_zeros)
+{
+ const std::size_t str_len = str.length();
+
+ if(my_exp < static_cast<INT64>(0))
+ {
+ // The number is less than one in magnitude. Insert the decimal
+ // point using "0" or "0." as well as the needed leading zeros.
+ const std::size_t minus_exp_minus_one = static_cast<std::size_t>(-my_exp - 1);
+ const std::string str_zero_insert((std::min)(minus_exp_minus_one, os_precision), static_cast<char>('0'));
+
+ str.insert(0u, "0." + str_zero_insert);
+
+ const INT64 n_pad = static_cast<INT64>(static_cast<INT64>(os_precision) - static_cast<INT64>(str_len + str_zero_insert.length()));
+
+ if(n_pad > static_cast<INT64>(0))
+ {
+ str.insert(str.end(), static_cast<std::size_t>(n_pad), static_cast<char>('0'));
+ }
+ }
+ else
+ {
+ // Insert the decimal point.
+ const std::size_t my_exp_plus_one = static_cast<std::size_t>(my_exp + 1);
+
+ str.insert(my_exp_plus_one, ".");
+
+ // Zero-extend the string to the given precision if necessary.
+ const INT64 n_pad = static_cast<INT64>(os_precision) - static_cast<INT64>(static_cast<INT64>(str_len) - (my_exp + 1));
+
+ if(n_pad > static_cast<INT64>(0))
+ {
+ str.insert(str.end(), static_cast<std::size_t>(n_pad), static_cast<char>('0'));
+ }
+ }
+
+ // Remove all trailing zeros if necessary.
+ if(trim_trailing_zeros)
+ {
+ const std::string::const_reverse_iterator rit_non_zero = std::find_if(str.rbegin(), str.rend(), char_is_nonzero_predicate);
+
+ if(rit_non_zero != str.rbegin())
+ {
+ const std::size_t ofs = str.length() - std::distance<std::string::const_reverse_iterator>(str.rbegin(), rit_non_zero);
+ str.erase(str.begin() + ofs, str.end());
+ }
+ }
+
+ // Remove the trailing decimal point if necessary.
+ if((*(str.end() - 1u) == static_cast<char>('.')) && (!my_showpoint))
+ {
+ str.erase(str.end() - 1u, str.end());
+ }
+}
+
 e_float e_float_base::my_ldexp (const e_float&, int) { return std::numeric_limits<e_float>::quiet_NaN(); }
 e_float e_float_base::my_frexp (const e_float&, int*) { return std::numeric_limits<e_float>::quiet_NaN(); }
 e_float e_float_base::my_fmod (const e_float&, const e_float&) { return std::numeric_limits<e_float>::quiet_NaN(); }

Modified: sandbox/e_float/libs/e_float/src/e_float/efx/e_float_efx.cpp
==============================================================================
--- sandbox/e_float/libs/e_float/src/e_float/efx/e_float_efx.cpp (original)
+++ sandbox/e_float/libs/e_float/src/e_float/efx/e_float_efx.cpp 2011-08-05 11:19:02 EDT (Fri, 05 Aug 2011)
@@ -1634,8 +1634,14 @@
 
 void efx::e_float::wr_string(std::string& str, std::ostream& os) const
 {
+ // Assess the format flags.
+ const std::ios::fmtflags my_flags = os.flags();
+
+ // Obtain the showpos flag.
+ const bool my_showpos = ((my_flags & std::ios::showpos) != static_cast<std::ios::fmtflags>(0u));
+
   // Handle INF and NaN.
- if(isnan()) { str = "NaN"; return; }
+ if(isnan()) { str = ((!isneg()) ? (my_showpos ? std::string("+INF") : std::string("INF")) : std::string("-INF")); return; }
   if(isinf()) { str = "INF"; return; }
 
   // Extract all of the digits from e_float, beginning with the first data element.
@@ -1650,9 +1656,7 @@
   const std::size_t os_precision = ((os.precision() > std::streamsize(-1)) ? static_cast<std::size_t>(os.precision())
                                                                             : static_cast<std::size_t>(0u));
 
- // Assess the format flags.
- const std::ios::fmtflags my_flags = os.flags();
-
+ // Determine the kind of output format requested (scientific, fixed, none).
   os_float_filed_type my_float_field;
 
   if ((my_flags & std::ios::scientific) != static_cast<std::ios::fmtflags>(0u)) { my_float_field = os_float_field_scientific; }
@@ -1740,7 +1744,6 @@
 
   // Obtain additional format information.
   const bool my_uppercase = ((my_flags & std::ios::uppercase) != static_cast<std::ios::fmtflags>(0u));
- const bool my_showpos = ((my_flags & std::ios::showpos) != static_cast<std::ios::fmtflags>(0u));
   const bool my_showpoint = ((my_flags & std::ios::showpoint) != static_cast<std::ios::fmtflags>(0u));
 
   // Write the output string in the desired format.
@@ -1819,119 +1822,6 @@
   }
 }
 
-void efx::e_float::wr_string_scientific(std::string& str,
- const INT64 my_exp,
- const std::size_t os_precision,
- const bool my_showpoint,
- const bool my_uppercase,
- const bool trim_trailing_zeros)
-{
- if(os_precision > static_cast<std::size_t>(str.length() - 1u))
- {
- // Zero-extend the string to the given precision if necessary.
- const std::size_t n_pad = static_cast<std::size_t>(os_precision - (str.length() - 1u));
-
- str.insert(str.end(), n_pad, static_cast<char>('0'));
- }
-
- // Insert the decimal point.
- str.insert(static_cast<std::size_t>(1u), ".");
-
- // Remove all trailing zeros if necessary.
- if(trim_trailing_zeros)
- {
- const std::string::const_reverse_iterator rit_non_zero = std::find_if(str.rbegin(), str.rend(), char_is_nonzero_predicate);
-
- if(rit_non_zero != str.rbegin())
- {
- const std::size_t ofs = str.length() - std::distance<std::string::const_reverse_iterator>(str.rbegin(), rit_non_zero);
- str.erase(str.begin() + ofs, str.end());
- }
- }
-
- // Remove the trailing decimal point if necessary.
- if((*(str.end() - 1u) == static_cast<char>('.')) && (!my_showpoint))
- {
- str.erase(str.end() - 1u, str.end());
- }
-
- // Append the exponent in uppercase or lower case, including its sign.
- const bool b_exp_is_neg = (my_exp < static_cast<INT64>(0));
- const UINT64 u_exp = static_cast<UINT64>(!b_exp_is_neg ? my_exp : static_cast<INT64>(-my_exp));
-
- str += (my_uppercase ? "E" : "e");
- str += (b_exp_is_neg ? "-" : "+");
- std::string str_exp = Util::lexical_cast(static_cast<INT64>(u_exp));
-
- // Format the exponent string to have a width that is an even multiple of three.
- const std::size_t str_exp_len = str_exp.length();
- const std::size_t str_exp_len_mod3 = static_cast<std::size_t>(str_exp_len % 3u);
- const std::size_t str_exp_len_pad = ((str_exp_len_mod3 != static_cast<std::size_t>(0u)) ? static_cast<std::size_t>(3u - (str_exp_len % 3u))
- : static_cast<std::size_t>(0u));
-
- str += std::string(str_exp_len_pad, static_cast<char>('0'));
- str += str_exp;
-}
-
-void efx::e_float::wr_string_fixed(std::string& str,
- const INT64 my_exp,
- const std::size_t os_precision,
- const bool my_showpoint,
- const bool trim_trailing_zeros)
-{
- const std::size_t str_len = str.length();
-
- if(my_exp < static_cast<INT64>(0))
- {
- // The number is less than one in magnitude. Insert the decimal
- // point using "0" or "0." as well as the needed leading zeros.
- const std::size_t minus_exp_minus_one = static_cast<std::size_t>(-my_exp - 1);
- const std::string str_zero_insert((std::min)(minus_exp_minus_one, os_precision), static_cast<char>('0'));
-
- str.insert(0u, "0." + str_zero_insert);
-
- const INT64 n_pad = static_cast<INT64>(static_cast<INT64>(os_precision) - static_cast<INT64>(str_len + str_zero_insert.length()));
-
- if(n_pad > static_cast<INT64>(0))
- {
- str.insert(str.end(), static_cast<std::size_t>(n_pad), static_cast<char>('0'));
- }
- }
- else
- {
- // Insert the decimal point.
- const std::size_t my_exp_plus_one = static_cast<std::size_t>(my_exp + 1);
-
- str.insert(my_exp_plus_one, ".");
-
- // Zero-extend the string to the given precision if necessary.
- const INT64 n_pad = static_cast<INT64>(os_precision) - static_cast<INT64>(static_cast<INT64>(str_len) - (my_exp + 1));
-
- if(n_pad > static_cast<INT64>(0))
- {
- str.insert(str.end(), static_cast<std::size_t>(n_pad), static_cast<char>('0'));
- }
- }
-
- // Remove all trailing zeros if necessary.
- if(trim_trailing_zeros)
- {
- const std::string::const_reverse_iterator rit_non_zero = std::find_if(str.rbegin(), str.rend(), char_is_nonzero_predicate);
-
- if(rit_non_zero != str.rbegin())
- {
- const std::size_t ofs = str.length() - std::distance<std::string::const_reverse_iterator>(str.rbegin(), rit_non_zero);
- str.erase(str.begin() + ofs, str.end());
- }
- }
-
- // Remove the trailing decimal point if necessary.
- if((*(str.end() - 1u) == static_cast<char>('.')) && (!my_showpoint))
- {
- str.erase(str.end() - 1u, str.end());
- }
-}
-
 bool efx::e_float::rd_string(const char* const s)
 {
   std::string str(s);

Modified: sandbox/e_float/libs/e_float/src/e_float/mpfr/e_float_mpfr.cpp
==============================================================================
--- sandbox/e_float/libs/e_float/src/e_float/mpfr/e_float_mpfr.cpp (original)
+++ sandbox/e_float/libs/e_float/src/e_float/mpfr/e_float_mpfr.cpp 2011-08-05 11:19:02 EDT (Fri, 05 Aug 2011)
@@ -21,6 +21,14 @@
 
 namespace
 {
+ typedef enum enum_os_float_field_type
+ {
+ os_float_field_scientific,
+ os_float_field_fixed,
+ os_float_field_none
+ }
+ os_float_filed_type;
+
   const double& d_log2(void)
   {
     static const double value_log2 = 0.3010299956639811952137389;
@@ -460,56 +468,193 @@
   }
 }
 
-void mpfr::e_float::wr_string(std::string& str, std::ostream& os) const
+void mpfr::e_float::get_raw_digits_from_scientific_string(std::string& str)
 {
- if(isnan())
+ // Get the raw digits from a string in scientific notation (lowercase, showpos).
+
+ // Erase the negative sign, if present.
+ if(str.at(0u) == static_cast<char>('-'))
   {
- str = "NaN";
- return;
+ str.erase(str.begin(), str.begin() + 1u);
   }
 
- if(isinf())
+ // Erase the exponent.
+ const std::size_t pos_letter_e = str.rfind(static_cast<char>('e'));
+
+ if(pos_letter_e != std::string::npos)
   {
- str = "INF";
- return;
+ str.erase(str.begin() + pos_letter_e, str.end());
   }
 
- static const std::streamsize p_min = static_cast<std::streamsize>(10);
- static const std::streamsize p_lim = static_cast<std::streamsize>(ef_digits10_tol);
- const std::streamsize p = (std::max)(os.precision(), p_min);
+ // Erase the decimal point.
+ const std::size_t pos_decimal_point = str.rfind(static_cast<char>('.'));
 
- const std::streamsize my_precision = (std::min)(p, p_lim);
+ if(pos_decimal_point != std::string::npos)
+ {
+ str.erase(str.begin() + pos_decimal_point, str.begin() + (pos_decimal_point + 1u));
+ }
+}
 
- const std::ios::fmtflags f = os.flags();
+void mpfr::e_float::wr_string(std::string& str, std::ostream& os) const
+{
+ // Assess the format flags.
+ const std::ios::fmtflags my_flags = os.flags();
 
- const bool my_uppercase = ((f & std::ios::uppercase) != static_cast<std::ios::fmtflags>(0u));
- const bool my_showpos = ((f & std::ios::showpos) != static_cast<std::ios::fmtflags>(0u));
- const bool my_scientific = ((f & std::ios::scientific) != static_cast<std::ios::fmtflags>(0u));
+ // Obtain the showpos flag.
+ const bool my_showpos = ((my_flags & std::ios::showpos) != static_cast<std::ios::fmtflags>(0u));
 
- // Create a format string such as "%+.99RNe"
- const std::string str_sign(my_showpos ? "%+." : "%.");
- const std::string str_prec(Util::lexical_cast(my_precision - (my_scientific ? 1 : 0)));
- const std::string str_case(my_scientific ? (my_uppercase ? "RNE" : "RNe") : (my_uppercase ? "RNG" : "RNg"));
+ // Handle INF and NaN.
+ if(isnan()) { str = ((!isneg()) ? (my_showpos ? std::string("+INF") : std::string("INF")) : std::string("-INF")); return; }
+ if(isinf()) { str = "INF"; return; }
 
- const std::string str_fmt = str_sign + (str_prec + str_case);
 
- std::tr1::array<char, static_cast<std::size_t>(e_float::ef_digits10_tol + 32)> buf = {{ static_cast<char>(0) }};
+ // Get the order-10 of the e_float. This is done using a partial string
+ // extraction with 10 decimal digits.
+ // Create a format string for 10-digits and scientific notation.
+ std::string str_fmt = std::string("%.10RNe");
 
+ // Get the ten digits.
+ std::tr1::array<char, static_cast<std::size_t>(e_float::ef_digits10_tol + 32)> buf = {{ static_cast<char>(0) }};
   ::mpfr_sprintf(buf.data(), str_fmt.c_str(), rop);
+ str = std::string(buf.data());
+
+ // Extract the exponent.
+ INT64 my_exp;
+
+ const std::size_t pos_letter_e = str.rfind(static_cast<char>('e'));
+
+ if(pos_letter_e != std::string::npos)
+ {
+ std::stringstream ss;
+ ss << (str.c_str() + (pos_letter_e + 1u));
+ ss >> my_exp;
+ }
+ else
+ {
+ my_exp = static_cast<INT64>(0);
+ }
+
+ // Get the output stream's precision and limit it to max_digits10.
+ // Erroneous negative precision will be set to the zero.
+ const std::size_t os_precision = ((os.precision() > std::streamsize(-1)) ? static_cast<std::size_t>(os.precision())
+ : static_cast<std::size_t>(0u));
+
+ // Determine the kind of output format requested (scientific, fixed, none).
+ os_float_filed_type my_float_field;
+
+ if ((my_flags & std::ios::scientific) != static_cast<std::ios::fmtflags>(0u)) { my_float_field = os_float_field_scientific; }
+ else if((my_flags & std::ios::fixed) != static_cast<std::ios::fmtflags>(0u)) { my_float_field = os_float_field_fixed; }
+ else { my_float_field = os_float_field_none; }
+
+ bool use_scientific = false;
+ bool use_fixed = false;
+
+ if (my_float_field == os_float_field_scientific) { use_scientific = true; }
+ else if(my_float_field == os_float_field_fixed) { use_fixed = true; }
+ else // os_float_field_none
+ {
+ if(my_exp < static_cast<INT64>(-4))
+ {
+ // The number is small in magnitude with a large, negative exponent.
+ // Use exponential notation.
+ use_scientific = true;
+ }
+ else if(my_exp >= (std::min)(static_cast<INT64>(std::numeric_limits<e_float>::digits10), (std::max)(static_cast<INT64>(os_precision), static_cast<INT64>(7))))
+ {
+ // The number is large in magnitude with a large, positive exponent.
+ // Use exponential notation.
+ use_scientific = true;
+ }
+ else
+ {
+ use_fixed = true;
+ }
+ }
+
+ // Ascertain the number of digits requested from e_float.
+ std::size_t the_number_of_digits_i_want_from_e_float = static_cast<std::size_t>(0u);
+ const std::size_t max10_plus_one = static_cast<std::size_t>(std::numeric_limits<e_float>::max_digits10 + 1);
 
+ if(use_scientific)
+ {
+ // The float-field is scientific. The number of digits is given by
+ // (1 + the ostream's precision), not to exceed (max_digits10 + 1).
+ const std::size_t prec_plus_one = static_cast<std::size_t>(1u + os_precision);
+ the_number_of_digits_i_want_from_e_float = (std::min)(max10_plus_one, prec_plus_one);
+ }
+ else if(use_fixed)
+ {
+ // The float-field is scientific. The number of all-digits depends
+ // on the form of the number.
+
+ if(my_exp >= static_cast<INT64>(0))
+ {
+ // If the number is larger than 1 in absolute value, then the number of
+ // digits is given by the width of the integer part plus the ostream's
+ // precision, not to exceed (max_digits10 + 1).
+ const std::size_t exp_plus_one = static_cast<std::size_t>(my_exp + 1);
+ const std::size_t exp_plus_one_plus_my_precision = static_cast<std::size_t>(exp_plus_one + os_precision);
+
+ the_number_of_digits_i_want_from_e_float = (std::min)(exp_plus_one_plus_my_precision, max10_plus_one);
+ }
+ else
+ {
+ const INT64 exp_plus_one = static_cast<INT64>(my_exp + 1);
+ const INT64 exp_plus_one_plus_my_precision = static_cast<INT64>(exp_plus_one + static_cast<INT64>(os_precision));
+
+ the_number_of_digits_i_want_from_e_float = (std::min)(static_cast<std::size_t>((std::max)(exp_plus_one_plus_my_precision, static_cast<INT64>(0))), max10_plus_one);
+ }
+ }
+
+ // Create a format string such as "%+.99RNe" for 100 digits
+ // in scientific notation with lowercase and noshowpos.
+ const std::size_t the_number_of_digits_scientific =
+ ((the_number_of_digits_i_want_from_e_float > static_cast<std::size_t>(1u)) ? static_cast<std::size_t>(the_number_of_digits_i_want_from_e_float - 1u)
+ : static_cast<std::size_t>(0u));
+ str_fmt = std::string("%.") + (Util::lexical_cast(the_number_of_digits_scientific) + "RNe");
+
+ // Get the string representation of the e_float in scientific notation (lowercase, noshowpos).
+ std::fill(buf.begin(), buf.end(), static_cast<char>(0));
+ ::mpfr_sprintf(buf.data(), str_fmt.c_str(), rop);
   str = std::string(buf.data());
 
- const std::size_t pos_E = (my_uppercase ? str.rfind('E') : str.rfind('e'));
+ // Obtain the raw digits from the scientific notation string.
+ // TBD: Well, this is a bit silly. First get the string in
+ // scientific notation, then reduce it to raw digits.
+ // Perhaps this can be improved.
+ get_raw_digits_from_scientific_string(str);
+
+ // Obtain additional format information.
+ const bool my_uppercase = ((my_flags & std::ios::uppercase) != static_cast<std::ios::fmtflags>(0u));
+ const bool my_showpoint = ((my_flags & std::ios::showpoint) != static_cast<std::ios::fmtflags>(0u));
+
+ // Write the output string in the desired format.
+ if (my_float_field == os_float_field_scientific) { wr_string_scientific(str, my_exp, os_precision, my_showpoint, my_uppercase); }
+ else if(my_float_field == os_float_field_fixed) { wr_string_fixed(str, my_exp, os_precision, my_showpoint); }
+ else // os_float_field_none
+ {
+ (use_scientific ? wr_string_scientific(str, my_exp, os_precision, my_showpoint, my_uppercase, true)
+ : wr_string_fixed(str, my_exp, os_precision, my_showpoint, true));
+ }
+
+ // Append the sign.
+ if (isneg()) { str.insert(static_cast<std::size_t>(0u), "-"); }
+ else if(my_showpos) { str.insert(static_cast<std::size_t>(0u), "+"); }
+
+ // Handle std::setw(...), std::setfill(...), std::left, std::right, std::internal.
+ const std::size_t my_width = ((os.width() >= static_cast<std::streamsize>(0)) ? static_cast<std::size_t>(os.width())
+ : static_cast<std::size_t>(0u));
 
- if(pos_E != std::string::npos)
+ if(my_width > str.length())
   {
- // Pad the exponent number field with additional zeros such that the width
- // of the exponent number field is equal to the width of ef_max_exp10.
- const std::size_t pos_exp = static_cast<std::string::size_type>(pos_E + 2u);
+ // Get the number of fill characters.
+ const std::size_t n_fill = static_cast<std::size_t>(my_width - str.length());
 
- const std::string::size_type width_of_exp = str.length() - pos_exp;
+ // Left-justify is the exception, std::right and std::internal justify right.
+ const bool my_left = ((my_flags & std::ios::left) != static_cast<std::ios::fmtflags>(0u));
 
- str.insert(pos_exp, std::string(width_of_exponent_field() - width_of_exp, static_cast<char>('0')));
+ // Justify left or right and insert the fill characters.
+ str.insert((my_left ? str.end() : str.begin()), n_fill, os.fill());
   }
 }
 


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