public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
* Re: libstdc++/5875: operator<<(double) doesn't allow printing full precision (3.0 regression)
@ 2002-03-07 16:38 paolo
0 siblings, 0 replies; 4+ messages in thread
From: paolo @ 2002-03-07 16:38 UTC (permalink / raw)
To: gcc-bugs, gcc-prs, nobody, paolo, snyder
Synopsis: operator<<(double) doesn't allow printing full precision (3.0 regression)
Responsible-Changed-From-To: unassigned->paolo
Responsible-Changed-By: paolo
Responsible-Changed-When: Thu Mar 7 16:38:24 2002
Responsible-Changed-Why:
Triaged.
State-Changed-From-To: open->analyzed
State-Changed-By: paolo
State-Changed-When: Thu Mar 7 16:38:24 2002
State-Changed-Why:
Hi!
I think your analysis is correct (as it was the first time,
by the way ;-) and I would suggest posting directly the
patch in the libstdc++ list. However, if you want to
provide a testcase, you should do this as a patch against
the concerned testsuite file, in the standard form based on
the use of VERIFY, portable (this is the tricky point)
across archs characterized by different machine precisions.
I mean, do you think it would be safe testing:
VERIFY(d - pi == 0.0) ??
I don't think so. What do you suggest then?
Ciao, Paolo.
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=5875
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: libstdc++/5875: operator<<(double) doesn't allow printing full precision (3.0 regression)
@ 2002-03-11 12:16 paolo
0 siblings, 0 replies; 4+ messages in thread
From: paolo @ 2002-03-11 12:16 UTC (permalink / raw)
To: gcc-bugs, gcc-prs, paolo, snyder
Synopsis: operator<<(double) doesn't allow printing full precision (3.0 regression)
State-Changed-From-To: analyzed->closed
State-Changed-By: paolo
State-Changed-When: Mon Mar 11 12:16:33 2002
State-Changed-Why:
Patch applied head and 3_1-branch. Thanks!
Paolo.
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=5875
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: libstdc++/5875: operator<<(double) doesn't allow printing full precision (3.0 regression)
@ 2002-03-08 12:16 Scott Snyder
0 siblings, 0 replies; 4+ messages in thread
From: Scott Snyder @ 2002-03-08 12:16 UTC (permalink / raw)
To: paolo; +Cc: gcc-prs
The following reply was made to PR libstdc++/5875; it has been noted by GNATS.
From: Scott Snyder <snyder@fnal.gov>
To: paolo@gcc.gnu.org, gcc-bugs@gcc.gnu.org, gcc-prs@gcc.gnu.org,
gcc-gnats@gcc.gnu.org
Cc:
Subject: Re: libstdc++/5875: operator<<(double) doesn't allow printing full precision (3.0 regression)
Date: 08 Mar 2002 14:09:01 -0600
> I think your analysis is correct (as it was the first time,
> by the way ;-) and I would suggest posting directly the
> patch in the libstdc++ list. However, if you want to
> provide a testcase, you should do this as a patch against
> the concerned testsuite file, in the standard form based on
> the use of VERIFY, portable (this is the tricky point)
> across archs characterized by different machine precisions.
> I mean, do you think it would be safe testing:
> VERIFY(d - pi == 0.0) ??
> I don't think so. What do you suggest then?
Oops --- i see i forgot to include the testsuite patch. Here's the full
patch again. I tried to ensure that they were equal to within a relative
error of DBL_EPSILON --- it may be that that's a little bit too small though.
I admit that as of this point, i've only tested it on linux/i86.
sss
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 -c -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/08 19:52:00
*************** namespace std
*** 610,616 ****
_M_convert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
_ValueT __v) const
{
! const int __max_digits = numeric_limits<_ValueT>::digits10;
streamsize __prec = __io.precision();
// Protect against sprintf() buffer overflows.
if (__prec > static_cast<streamsize>(__max_digits))
--- 610,618 ----
_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
! // 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))
Index: testsuite/27_io/ostream_inserter_arith.cc
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/testsuite/27_io/ostream_inserter_arith.cc,v
retrieving revision 1.15
diff -u -p -c -r1.15 ostream_inserter_arith.cc
*** ostream_inserter_arith.cc 2002/01/31 00:03:31 1.15
--- ostream_inserter_arith.cc 2002/03/08 19:51:23
***************
*** 20,25 ****
--- 20,27 ----
// USA.
#include <cstdio> // for sprintf
+ #include <cmath> // for abs
+ #include <cfloat> // for DBL_EPSILON
#include <iostream>
#include <iomanip>
#include <locale>
*************** test04()
*** 355,360 ****
--- 357,377 ----
return 0;
}
+ int
+ test05()
+ {
+ double pi = 3.14159265358979323846;
+ ostringstream ostr;
+ ostr.precision(20);
+ ostr << pi;
+ string sval = ostr.str();
+ istringstream istr (sval);
+ double d;
+ istr >> d;
+ VERIFY (abs(pi-d)/pi < DBL_EPSILON);
+ return 0;
+ }
+
int
main()
{
*************** main()
*** 362,367 ****
--- 379,385 ----
test02();
test03();
test04();
+ test05();
#ifdef TEST_NUMPUT_VERBOSE
cout << "Test passed!" << endl;
#endif
^ permalink raw reply [flat|nested] 4+ messages in thread
* libstdc++/5875: operator<<(double) doesn't allow printing full precision (3.0 regression)
@ 2002-03-07 13:26 snyder
0 siblings, 0 replies; 4+ messages in thread
From: snyder @ 2002-03-07 13:26 UTC (permalink / raw)
To: gcc-gnats
>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:
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2002-03-11 20:16 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-03-07 16:38 libstdc++/5875: operator<<(double) doesn't allow printing full precision (3.0 regression) paolo
-- strict thread matches above, loose matches on Subject: below --
2002-03-11 12:16 paolo
2002-03-08 12:16 Scott Snyder
2002-03-07 13:26 snyder
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).