public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
From: snyder@fnal.gov
To: gcc-gnats@gcc.gnu.org
Subject: libstdc++/5875: operator<<(double) doesn't allow printing full precision (3.0 regression)
Date: Thu, 07 Mar 2002 13:26:00 -0000	[thread overview]
Message-ID: <200203072113.g27LDZR02375@karma.fnal.gov> (raw)


>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:


             reply	other threads:[~2002-03-07 21:26 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-03-07 13:26 snyder [this message]
2002-03-07 16:38 paolo
2002-03-08 12:16 Scott Snyder
2002-03-11 12:16 paolo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200203072113.g27LDZR02375@karma.fnal.gov \
    --to=snyder@fnal.gov \
    --cc=gcc-gnats@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).