From fd3a4cb92d936976027b884fcd9db5b75fb4b8c7 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 13 Mar 2011 13:53:54 +0000 Subject: [PATCH] Added precision parameter to wxString::From[C]Double(). Optionally support fixed precision in wxString::FromDouble() and FromCDouble() methods. This is mostly useful for the latter to be able to format numbers in portable way (using dot as decimal separator) without loss of precision but also do it for the former for consistency. Closes #12973. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@67181 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + include/wx/string.h | 8 ++++---- interface/wx/string.h | 18 +++++++++++++----- src/common/string.cpp | 30 ++++++++++++++++++++++++++++-- tests/strings/strings.cpp | 17 +++++++++++------ 5 files changed, 57 insertions(+), 17 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 11cc48733e..e74fcd02f1 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -438,6 +438,7 @@ All: - Added wxIntegerValidator<> and wxFloatingPointValidator<> validators. - Added wxIMAGE_OPTION_GIF_COMMENT to read and write GIF comments (troelsk). - Added wxStack<> template class. +- Added precision parameter to wxString::From[C]Double(). Unix: diff --git a/include/wx/string.h b/include/wx/string.h index f51d3f0660..c7f380b5ec 100644 --- a/include/wx/string.h +++ b/include/wx/string.h @@ -2326,12 +2326,12 @@ public: // convert to a double bool ToCDouble(double *val) const; - // create a string representing the given floating point number + // create a string representing the given floating point number with the + // default (like %g) or fixed (if precision >=0) precision // in the current locale - static wxString FromDouble(double val) - { return wxString::Format(wxS("%g"), val); } + static wxString FromDouble(double val, int precision = -1); // in C locale - static wxString FromCDouble(double val); + static wxString FromCDouble(double val, int precision = -1); #ifndef wxNEEDS_WXSTRING_PRINTF_MIXIN // formatted input/output diff --git a/interface/wx/string.h b/interface/wx/string.h index f6ca6cd0f5..7d6d443044 100644 --- a/interface/wx/string.h +++ b/interface/wx/string.h @@ -1535,29 +1535,37 @@ public: Unlike FromDouble() the string returned by this function always uses the period character as decimal separator, independently of the current - locale. + locale. Otherwise its behaviour is identical to the other function. @since 2.9.1 @see ToCDouble() */ - static wxString FromCDouble(double val); + static wxString FromCDouble(double val, int precision = -1); /** Returns a string with the textual representation of the number. - This is a simple wrapper for @code wxString::Format("%g", val) - @endcode. + For the default value of @a precision, this function behaves as a + simple wrapper for @code wxString::Format("%g", val) @endcode. If @a + precision is positive (or zero), the @c %.Nf format is used with the + given precision value. Notice that the string returned by this function uses the decimal separator appropriate for the current locale, e.g. @c "," and not a period in French locale. Use FromCDouble() if this is unwanted. + @param val + The value to format. + @param precision + The number of fractional digits to use in or -1 to use the most + appropriate format. This parameter is new in wxWidgets 2.9.2. + @since 2.9.1 @see ToDouble() */ - static wxString FromDouble(double val); + static wxString FromDouble(double val, int precision = -1); //@{ /** diff --git a/src/common/string.cpp b/src/common/string.cpp index fa7bb0c2f8..6cfea4102c 100644 --- a/src/common/string.cpp +++ b/src/common/string.cpp @@ -1839,17 +1839,43 @@ bool wxString::ToCDouble(double *pVal) const // ---------------------------------------------------------------------------- /* static */ -wxString wxString::FromCDouble(double val) +wxString wxString::FromDouble(double val, int precision) { + wxCHECK_MSG( precision >= -1, wxString(), "Invalid negative precision" ); + + wxString format; + if ( precision == -1 ) + { + format = "%g"; + } + else // Use fixed precision. + { + format.Printf("%%.%df", precision); + } + + return wxString::Format(format, val); +} + +/* static */ +wxString wxString::FromCDouble(double val, int precision) +{ + wxCHECK_MSG( precision >= -1, wxString(), "Invalid negative precision" ); + #if wxUSE_STD_IOSTREAM && wxUSE_STD_STRING // We assume that we can use the ostream and not wstream for numbers. wxSTD ostringstream os; + if ( precision != -1 ) + { + os.precision(precision); + os.setf(std::ios::fixed, std::ios::floatfield); + } + os << val; return os.str(); #else // !wxUSE_STD_IOSTREAM // Can't use iostream locale support, fall back to the manual method // instead. - wxString s = FromDouble(val); + wxString s = FromDouble(val, precision); #if wxUSE_INTL wxString sep = wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER); diff --git a/tests/strings/strings.cpp b/tests/strings/strings.cpp index 06b2d94fb4..0f12864bad 100644 --- a/tests/strings/strings.cpp +++ b/tests/strings/strings.cpp @@ -762,25 +762,30 @@ void StringTestCase::FromDouble() static const struct FromDoubleTestData { double value; + int prec; const char *str; } testData[] = { - { 1.23, "1.23" }, + { 1.23, -1, "1.23" }, // NB: there are no standards about the minimum exponent width // and newer MSVC versions use 3 digits as minimum exponent // width while GNU libc uses 2 digits as minimum width... #ifdef wxUSING_VC_CRT_IO - { -3e-10, "-3e-010" }, + { -3e-10, -1, "-3e-010" }, #else - { -3e-10, "-3e-10" }, + { -3e-10, -1, "-3e-10" }, #endif - { -0.45678, "-0.45678" }, + { -0.45678, -1, "-0.45678" }, + { 1.2345678, 0, "1" }, + { 1.2345678, 1, "1.2" }, + { 1.2345678, 2, "1.23" }, + { 1.2345678, 3, "1.235" }, }; for ( unsigned n = 0; n < WXSIZEOF(testData); n++ ) { const FromDoubleTestData& td = testData[n]; - CPPUNIT_ASSERT_EQUAL( td.str, wxString::FromCDouble(td.value) ); + CPPUNIT_ASSERT_EQUAL( td.str, wxString::FromCDouble(td.value, td.prec) ); } if ( !wxLocale::IsAvailable(wxLANGUAGE_FRENCH) ) @@ -795,7 +800,7 @@ void StringTestCase::FromDouble() wxString str(td.str); str.Replace(".", ","); - CPPUNIT_ASSERT_EQUAL( str, wxString::FromDouble(td.value) ); + CPPUNIT_ASSERT_EQUAL( str, wxString::FromDouble(td.value, td.prec) ); } } -- 2.45.2