This is the mail archive of the gcc-prs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

libstdc++/5875: operator<<(double) doesn't allow printing full precision (3.0 regression)



>Number:         5875
>Category:       libstdc++
>Synopsis:       operator<<(double) doesn't allow printing full precision (3.0 regression)
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Mar 07 13:26:02 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     scott snyder
>Release:        3.1 20020303 (prerelease)
>Organization:
>Environment:
System: Linux karma 2.4.9-13 #1 Tue Oct 30 20:11:04 EST 2001 i686 unknown
Architecture: i686

	
host: i686-pc-linux-gnu
build: i686-pc-linux-gnu
target: i686-pc-linux-gnu
configured with: ../egcs/configure --prefix=/usr/local/egcs --enable-threads=posix --enable-long-long --enable-languages=c,c++,f77 : (reconfigured) 
>Description:

We have code that expects, after suitably widening the precision,
to be able to write out a double to a stream using operator<<,
then read it back using operator>> and get the same value to within
a relative error of DBL_EPSILON.  This used to be the case with gcc 3.0,
but is no longer true with gcc 3.1.

A little test program is below.
When i build this (on linux/ia86) with gcc 3.0.2, it prints `0'.
But when i build this with the gcc 3.1 branch, it prints `-3.10862e-15'.
So this is a relative error of about 1e-15, which is about 5 times
larger than DBL_EPSILON.

This comes about because the precision that the user specifies is clamped
to a maximum of numeric_limits<T>::digits10.  However, this is the floor
of the `true' fractional value --- limiting yourself to that many digits
can lose a couple bits off the end.

Several years ago, i submitted a patch to increase this limit by a couple
to avoid this problem:

2000-03-29  scott snyder  <snyder@fnal.gov>

        * bits/locale_facets.tcc (do_put): Allow a couple extra digits of
        precision beyond that which we get from numeric_limits::digits10.

However, it looks like when the locale code was revised between 3.0 and 3.1,
this change got lost.

Below is a patch to fix this (along with an addition to the testsuite,
so that it doesn't get lost again).


>How-To-Repeat:

-- x.cc ------------------------------------------------------------------
#include <sstream>
#include <iostream>
#include <string>

int main ()
{
  double pi = 3.14159265358979323846;
  std::ostringstream ostr;
  ostr.precision(20);
  ostr << pi;
  std::string sval = ostr.str();
  std::istringstream istr (sval);
  double d;
  istr >> d;
  std::cout << d - pi << "\n";
  return 0;
}
--------------------------------------------------------------------------

>Fix:


2002-03-06  scott snyder  <snyder@fnal.gov>

	* include/bits/locale_facets.tcc (num_put::_M_convert_float):
	Allow one more digit of precision.
	* testsuite/27_io/ostream_inserter_arith.cc: Test that we can
	write a double and read back in the same value.

Index: include/bits/locale_facets.tcc
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/include/bits/locale_facets.tcc,v
retrieving revision 1.63.2.3
diff -u -p -r1.63.2.3 locale_facets.tcc
--- locale_facets.tcc	2002/03/05 19:05:05	1.63.2.3
+++ locale_facets.tcc	2002/03/07 19:43:29
@@ -610,7 +610,9 @@ namespace std
       _M_convert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
 		       _ValueT __v) const
       {
-	const int __max_digits = numeric_limits<_ValueT>::digits10;
+        // 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;
 	streamsize __prec = __io.precision();
 	// Protect against sprintf() buffer overflows.
 	if (__prec > static_cast<streamsize>(__max_digits))

>Release-Note:
>Audit-Trail:
>Unformatted:


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]