From: Paolo Carlini Date: Mon, 6 Jan 2003 15:51:49 +0000 (+0100) Subject: re PR libstdc++/9151 (std::setprecision limited to 16 digits when outputting a double... X-Git-Tag: releases/gcc-3.2.2~138 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f4b2ba0956dde87cc5e6de0c5893ddcd13236f47;p=thirdparty%2Fgcc.git re PR libstdc++/9151 (std::setprecision limited to 16 digits when outputting a double to a stream) 2003-01-06 Paolo Carlini 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: r60941 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 09d86d8676f0..0cd1b50a19b8 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,12 @@ +2003-01-06 Paolo Carlini + + 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 * testsuite/lib/libstdc++-v3-dg.exp (libstdc++-v3-init): diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc index ce6f3d7d5ffa..1bf3d7ce7962 100644 --- a/libstdc++-v3/include/bits/locale_facets.tcc +++ b/libstdc++-v3/include/bits/locale_facets.tcc @@ -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(__max_digits)) @@ -1628,7 +1633,7 @@ namespace std // Find smallest matching string. size_t __minlen = 10; for (size_t __i2 = 0; __i2 < __nmatches; ++__i2) - __minlen = min(__minlen, + __minlen = min(__minlen, __traits_type::length(__names[__matches[__i2]])); if (__pos < __minlen && __beg != __end) diff --git a/libstdc++-v3/testsuite/27_io/ostream_inserter_arith.cc b/libstdc++-v3/testsuite/27_io/ostream_inserter_arith.cc index 041f3149011f..e4e618d68d86 100644 --- a/libstdc++-v3/testsuite/27_io/ostream_inserter_arith.cc +++ b/libstdc++-v3/testsuite/27_io/ostream_inserter_arith.cc @@ -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::digits10 + 2; + double oval = numeric_limits::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