From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30780 invoked by alias); 7 Mar 2002 21:26:04 -0000 Mailing-List: contact gcc-prs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-prs-owner@gcc.gnu.org Received: (qmail 30743 invoked by uid 71); 7 Mar 2002 21:26:02 -0000 Resent-Date: 7 Mar 2002 21:26:02 -0000 Resent-Message-ID: <20020307212602.30742.qmail@sources.redhat.com> Resent-From: gcc-gnats@gcc.gnu.org (GNATS Filer) Resent-To: nobody@gcc.gnu.org Resent-Cc: gcc-prs@gcc.gnu.org, gcc-bugs@gcc.gnu.org Resent-Reply-To: gcc-gnats@gcc.gnu.org, snyder@fnal.gov Received:(qmail 14781 invoked from network); 7 Mar 2002 21:17:16 -0000 Received: from unknown (HELO karma.fnal.gov) (131.225.227.24) by sources.redhat.com with SMTP; 7 Mar 2002 21:17:16 -0000 Received: (from sss@localhost) by karma.fnal.gov (8.11.6/8.11.6) id g27LDZR02375; Thu, 7 Mar 2002 15:13:35 -0600 Message-Id:<200203072113.g27LDZR02375@karma.fnal.gov> Date: Thu, 07 Mar 2002 13:26:00 -0000 From: snyder@fnal.gov Reply-To: snyder@fnal.gov To: gcc-gnats@gcc.gnu.org X-Send-Pr-Version:3.113 Subject: libstdc++/5875: operator<<(double) doesn't allow printing full precision (3.0 regression) X-SW-Source: 2002-03/txt/msg00258.txt.bz2 List-Id: >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::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 * 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 #include #include 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 * 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(__max_digits)) >Release-Note: >Audit-Trail: >Unformatted: