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
This commit is contained in:
Vadim Zeitlin
2011-03-13 13:53:54 +00:00
parent 17a8f66c75
commit fd3a4cb92d
5 changed files with 57 additions and 17 deletions

View File

@@ -438,6 +438,7 @@ All:
- Added wxIntegerValidator<> and wxFloatingPointValidator<> validators. - Added wxIntegerValidator<> and wxFloatingPointValidator<> validators.
- Added wxIMAGE_OPTION_GIF_COMMENT to read and write GIF comments (troelsk). - Added wxIMAGE_OPTION_GIF_COMMENT to read and write GIF comments (troelsk).
- Added wxStack<> template class. - Added wxStack<> template class.
- Added precision parameter to wxString::From[C]Double().
Unix: Unix:

View File

@@ -2326,12 +2326,12 @@ public:
// convert to a double // convert to a double
bool ToCDouble(double *val) const; 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 // in the current locale
static wxString FromDouble(double val) static wxString FromDouble(double val, int precision = -1);
{ return wxString::Format(wxS("%g"), val); }
// in C locale // in C locale
static wxString FromCDouble(double val); static wxString FromCDouble(double val, int precision = -1);
#ifndef wxNEEDS_WXSTRING_PRINTF_MIXIN #ifndef wxNEEDS_WXSTRING_PRINTF_MIXIN
// formatted input/output // formatted input/output

View File

@@ -1535,29 +1535,37 @@ public:
Unlike FromDouble() the string returned by this function always uses Unlike FromDouble() the string returned by this function always uses
the period character as decimal separator, independently of the current 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 @since 2.9.1
@see ToCDouble() @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. Returns a string with the textual representation of the number.
This is a simple wrapper for @code wxString::Format("%g", val) For the default value of @a precision, this function behaves as a
@endcode. 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 Notice that the string returned by this function uses the decimal
separator appropriate for the current locale, e.g. @c "," and not a separator appropriate for the current locale, e.g. @c "," and not a
period in French locale. Use FromCDouble() if this is unwanted. 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 @since 2.9.1
@see ToDouble() @see ToDouble()
*/ */
static wxString FromDouble(double val); static wxString FromDouble(double val, int precision = -1);
//@{ //@{
/** /**

View File

@@ -1839,17 +1839,43 @@ bool wxString::ToCDouble(double *pVal) const
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/* static */ /* 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 #if wxUSE_STD_IOSTREAM && wxUSE_STD_STRING
// We assume that we can use the ostream and not wstream for numbers. // We assume that we can use the ostream and not wstream for numbers.
wxSTD ostringstream os; wxSTD ostringstream os;
if ( precision != -1 )
{
os.precision(precision);
os.setf(std::ios::fixed, std::ios::floatfield);
}
os << val; os << val;
return os.str(); return os.str();
#else // !wxUSE_STD_IOSTREAM #else // !wxUSE_STD_IOSTREAM
// Can't use iostream locale support, fall back to the manual method // Can't use iostream locale support, fall back to the manual method
// instead. // instead.
wxString s = FromDouble(val); wxString s = FromDouble(val, precision);
#if wxUSE_INTL #if wxUSE_INTL
wxString sep = wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxString sep = wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT,
wxLOCALE_CAT_NUMBER); wxLOCALE_CAT_NUMBER);

View File

@@ -762,25 +762,30 @@ void StringTestCase::FromDouble()
static const struct FromDoubleTestData static const struct FromDoubleTestData
{ {
double value; double value;
int prec;
const char *str; const char *str;
} testData[] = } testData[] =
{ {
{ 1.23, "1.23" }, { 1.23, -1, "1.23" },
// NB: there are no standards about the minimum exponent width // NB: there are no standards about the minimum exponent width
// and newer MSVC versions use 3 digits as minimum exponent // and newer MSVC versions use 3 digits as minimum exponent
// width while GNU libc uses 2 digits as minimum width... // width while GNU libc uses 2 digits as minimum width...
#ifdef wxUSING_VC_CRT_IO #ifdef wxUSING_VC_CRT_IO
{ -3e-10, "-3e-010" }, { -3e-10, -1, "-3e-010" },
#else #else
{ -3e-10, "-3e-10" }, { -3e-10, -1, "-3e-10" },
#endif #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++ ) for ( unsigned n = 0; n < WXSIZEOF(testData); n++ )
{ {
const FromDoubleTestData& td = 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) ) if ( !wxLocale::IsAvailable(wxLANGUAGE_FRENCH) )
@@ -795,7 +800,7 @@ void StringTestCase::FromDouble()
wxString str(td.str); wxString str(td.str);
str.Replace(".", ","); str.Replace(".", ",");
CPPUNIT_ASSERT_EQUAL( str, wxString::FromDouble(td.value) ); CPPUNIT_ASSERT_EQUAL( str, wxString::FromDouble(td.value, td.prec) );
} }
} }