This is the mail archive of the gcc-bugs@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]

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



>    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


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