|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r73459 - in sandbox/e_float: boost/e_float libs/e_float/src/e_float/efx
From: e_float_at_[hidden]
Date: 2011-07-31 05:46:32
Author: christopher_kormanyos
Date: 2011-07-31 05:46:29 EDT (Sun, 31 Jul 2011)
New Revision: 73459
URL: http://svn.boost.org/trac/boost/changeset/73459
Log:
- Completed the write to std::ostream functions.
Text files modified:
sandbox/e_float/boost/e_float/e_float_efx.hpp | 17 ++
sandbox/e_float/libs/e_float/src/e_float/efx/e_float_efx.cpp | 220 ++++++++++++++++++++++++---------------
2 files changed, 149 insertions(+), 88 deletions(-)
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-07-31 05:46:29 EDT (Sun, 31 Jul 2011)
@@ -180,9 +180,22 @@
private:
virtual void wr_string(std::string& str, std::ostream& os) const;
- void wr_string_scientific(std::string& str, const INT64 my_exp, const std::size_t os_precision, const bool my_showpos, const bool my_uppercase) const;
- void wr_string_fixed (std::string& str, const INT64 my_exp, const std::size_t os_precision, const bool my_showpos, const bool my_showpoint, const bool trim_trailing_zeros = false) const;
virtual bool rd_string(const char* const s);
+
+ static void e_float::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/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-07-31 05:46:29 EDT (Sun, 31 Jul 2011)
@@ -34,6 +34,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;
+
// Emphasize: This template class can be used with native
// floating-point types like float, double and long double.
template<typename native_float_type>
@@ -1428,6 +1436,52 @@
return val;
}
+void efx::e_float::round_output_string(std::string& str, INT64& my_exp, const std::size_t number_of_digits)
+{
+ // Cut the output to the size of the precision.
+ if(str.length() > number_of_digits)
+ {
+ // Get the digit after the last needed digit for rounding
+ const UINT32 round = static_cast<UINT32>(static_cast<UINT32>(str.at(number_of_digits)) - static_cast<UINT32>('0'));
+
+ // Truncate the string
+ str = str.substr(static_cast<std::size_t>(0u), number_of_digits);
+
+ if(round >= static_cast<UINT32>(5u))
+ {
+ std::size_t ix = static_cast<std::size_t>(str.length() - 1u);
+
+ // Every trailing 9 must be rounded up
+ while(ix && (static_cast<INT32>(str.at(ix)) - static_cast<INT32>('0') == static_cast<INT32>(9)))
+ {
+ str.at(ix) = static_cast<char>('0');
+ --ix;
+ }
+
+ if(!ix)
+ {
+ // There were nothing but trailing nines.
+ if(static_cast<INT32>(static_cast<INT32>(str.at(ix)) - static_cast<INT32>(0x30)) == static_cast<INT32>(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 last digit.
+ ++str[ix];
+ }
+ }
+ }
+}
+
void efx::e_float::wr_string(std::string& str, std::ostream& os) const
{
// Handle INF and NaN.
@@ -1461,24 +1515,33 @@
// Assess the format flags.
const std::ios::fmtflags f = 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));
- const bool my_fixed = ((!my_scientific) && ((f & std::ios::fixed) != static_cast<std::ios::fmtflags>(0u)));
- const bool my_showpoint = ((f & std::ios::showpoint) != static_cast<std::ios::fmtflags>(0u));
+ os_float_filed_type my_float_field;
+
+ if((f & std::ios::scientific) != static_cast<std::ios::fmtflags>(0u))
+ {
+ my_float_field = os_float_field_scientific;
+ }
+ else if((f & 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_scientific)
+ if(my_float_field == os_float_field_scientific)
{
use_scientific = true;
}
- else if(my_fixed)
+ else if(my_float_field == os_float_field_fixed)
{
use_fixed = true;
}
- else // The float-field is not set.
+ else // os_float_field_none
{
if(my_exp < static_cast<INT64>(-4))
{
@@ -1534,70 +1597,54 @@
}
// Cut the output to the size of the precision.
- if(str.length() > the_number_of_digits_i_want_from_e_float)
- {
- // Get the digit after the last needed digit for rounding
- const UINT32 round = static_cast<UINT32>(static_cast<UINT32>(str.at(the_number_of_digits_i_want_from_e_float)) - static_cast<UINT32>('0'));
-
- // Truncate the string
- str = str.substr(static_cast<std::size_t>(0u), the_number_of_digits_i_want_from_e_float);
-
- if(round >= static_cast<UINT32>(5u))
- {
- std::size_t ix = static_cast<std::size_t>(str.length() - 1u);
-
- // Every trailing 9 must be rounded up
- while(ix && (static_cast<INT32>(str.at(ix)) - static_cast<INT32>('0') == static_cast<INT32>(9)))
- {
- str.at(ix) = static_cast<char>('0');
- --ix;
- }
+ round_output_string(str, my_exp, the_number_of_digits_i_want_from_e_float);
- if(!ix)
- {
- // There were nothing but trailing nines.
- if(static_cast<INT32>(static_cast<INT32>(str.at(ix)) - static_cast<INT32>(0x30)) == static_cast<INT32>(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 last digit.
- ++str[ix];
- }
- }
- }
+ // Obtain additional format information.
+ 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_showpoint = ((f & std::ios::showpoint) != static_cast<std::ios::fmtflags>(0u));
- if(my_scientific)
+ // 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_showpos, my_uppercase);
+ wr_string_scientific(str, my_exp, os_precision, my_showpoint, my_uppercase);
}
- else if(my_fixed)
+ else if(my_float_field == os_float_field_fixed)
{
- wr_string_fixed(str, my_exp, os_precision, my_showpos, my_showpoint);
+ wr_string_fixed(str, my_exp, os_precision, my_showpoint);
}
- else // The float-field is not set.
+ else // os_float_field_none
{
if(use_scientific)
{
- wr_string_scientific(str, my_exp, os_precision, my_showpos, my_uppercase);
+ wr_string_scientific(str, my_exp, os_precision, my_showpoint, my_uppercase, true);
}
- else if(use_fixed)
+ else // use_fixed
{
- wr_string_fixed(str, my_exp, os_precision, my_showpos, my_showpoint, 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), "+");
}
}
}
-void efx::e_float::wr_string_scientific(std::string& str, const INT64 my_exp, const std::size_t os_precision, const bool my_showpos, const bool my_uppercase) const
+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))
{
@@ -1610,6 +1657,24 @@
// 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.back() == static_cast<char>('.')) && (!my_showpoint))
+ {
+ str.pop_back();
+ }
+
// 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));
@@ -1626,22 +1691,13 @@
str += std::string(str_exp_len_pad, static_cast<char>('0'));
str += str_exp;
-
- // 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), "+");
- }
- }
}
-void efx::e_float::wr_string_fixed(std::string& str, const INT64 my_exp, const std::size_t os_precision, const bool my_showpos, const bool my_showpoint, const bool trim_trailing_zeros) const
+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();
@@ -1677,31 +1733,23 @@
}
}
+ // Remove all trailing zeros if necessary.
if(trim_trailing_zeros)
{
- while(str.back() == static_cast<char>('0'))
+ 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())
{
- str.pop_back();
+ 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.back() == static_cast<char>('.')) && (!my_showpoint))
{
str.pop_back();
}
-
- // 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), "+");
- }
- }
}
bool efx::e_float::rd_string(const char* const s)
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