This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: libstdc++/5875: operator<<(double) doesn't allow printing full precision (3.0 regression)
- From: Scott Snyder <snyder at fnal dot gov>
- To: paolo at gcc dot gnu dot org, gcc-bugs at gcc dot gnu dot org, gcc-prs at gcc dot gnu dot org, gcc-gnats at gcc dot gnu dot org
- Date: 08 Mar 2002 14:09:01 -0600
- Subject: Re: libstdc++/5875: operator<<(double) doesn't allow printing full precision (3.0 regression)
- References: <20020308003824.8537.qmail@sources.redhat.com>
> 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