re PR libstdc++/9151 (std::setprecision limited to 16 digits when outputting a double to a stream)

2003-01-06  Paolo Carlini  <pcarlini@unitus.it>

	PR libstdc++/9151
	* include/bits/locale_facets.cc (num_put::_M_convert_float):
	Limit __prec to digits10 + 2, not digits10 + 1, taking into
	account the possibility of %{g,G} conversion specifiers
	inside _S_format_float.
	* testsuite/27_io/ostream_inserter_arith.cc (test06): Add.

From-SVN: r60939
This commit is contained in:
Paolo Carlini 2003-01-06 16:32:16 +01:00 committed by Paolo Carlini
parent 8de6a6df28
commit 87117aa2f3
3 changed files with 37 additions and 3 deletions

View File

@ -1,3 +1,12 @@
2003-01-06 Paolo Carlini <pcarlini@unitus.it>
PR libstdc++/9151
* include/bits/locale_facets.cc (num_put::_M_convert_float):
Limit __prec to digits10 + 2, not digits10 + 1, taking into
account the possibility of %{g,G} conversion specifiers
inside _S_format_float.
* testsuite/27_io/ostream_inserter_arith.cc (test06): Add.
2003-01-06 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* testsuite/lib/libstdc++-v3-dg.exp (libstdc++-v3-init,

View File

@ -622,9 +622,14 @@ namespace std
_M_convert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
_ValueT __v) const
{
// Note: digits10 is rounded down. We need to add 1 to ensure
// Note: digits10 is rounded down: we need to add 1 to ensure
// we get the full available precision.
const int __max_digits = numeric_limits<_ValueT>::digits10 + 1;
// Then, in general, one more 1 needs to be added since, when the
// %{g,G} conversion specifiers are chosen inside _S_format_float, the
// precision field is "the maximum number of significant digits", *not*
// the "number of digits to appear after the decimal point", as happens
// for %{e,E,f,F} (C99, 7.19.6.1,4).
const int __max_digits = numeric_limits<_ValueT>::digits10 + 2;
streamsize __prec = __io.precision();
if (__prec > static_cast<streamsize>(__max_digits))

View File

@ -368,7 +368,26 @@ test05()
istringstream istr (sval);
double d;
istr >> d;
VERIFY (abs(pi-d)/pi < DBL_EPSILON);
VERIFY( abs(pi-d)/pi < DBL_EPSILON );
return 0;
}
// libstdc++/9151
int
test06()
{
int prec = numeric_limits<double>::digits10 + 2;
double oval = numeric_limits<double>::min();
stringstream ostr;
ostr.precision(prec);
ostr << oval;
string sval = ostr.str();
istringstream istr (sval);
double ival;
istr >> ival;
VERIFY( abs(oval-ival)/oval < DBL_EPSILON );
return 0;
}
@ -380,6 +399,7 @@ main()
test03();
test04();
test05();
test06();
#ifdef TEST_NUMPUT_VERBOSE
cout << "Test passed!" << endl;
#endif