re PR libstdc++/9151 (std::setprecision limited to 16 digits when outputting a double...
authorPaolo Carlini <pcarlini@unitus.it>
Mon, 6 Jan 2003 15:32:16 +0000 (16:32 +0100)
committerPaolo Carlini <paolo@gcc.gnu.org>
Mon, 6 Jan 2003 15:32:16 +0000 (15:32 +0000)
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

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/locale_facets.tcc
libstdc++-v3/testsuite/27_io/ostream_inserter_arith.cc

index 1ea147cd224a113c0be4eef2afa9317c571776e6..4f9d78d2ab3b62150b092d0021ae93515611d404 100644 (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,
index 75def8f5a61ddfad7f3484dcba09b9b4c488d6c1..26915e71c9e1b6a1d390f49888b0fae02ae6be71 100644 (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))
index 041f3149011fdf58be3941b13a6e0a063277f2f6..e4e618d68d86b84bc49966f4f3adb76d11092367 100644 (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