This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ 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]

[3.3 Patch] Fix libstdc++/14220


Hi all, hi Gaby,

I'd like to apply this fix to the branch *before* mainline and 3_4,
since seems quite obvious and there we are still working on the fast
output of floats, which will change completely the affected function.

In a nutshell, without the patch this testcase outputs two different
numbers, whereas, according to 22.2.2.2.2, those should be identical
since everything must go as if printf were called:

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
 cout << fixed << setprecision(25) << 5.55555555e-17 << '\n';
 printf("%.25f\n", 5.55555555e-17);
}

Tested x86-linux.

Ok?

Paolo.

////////////
2004-02-22  Paolo Carlini  <pcarlini@suse.de>

	PR libstdc++/14220
	* include/bits/locale_facets.tcc (num_put<>::_M_convert_float):
	Don't clip the precision passed down to __convert_from_v:
	22.2.2.2.2 nowhere says so.

diff -urN libstdc++-v3-orig/include/bits/locale_facets.tcc libstdc++-v3/include/bits/locale_facets.tcc
--- libstdc++-v3-orig/include/bits/locale_facets.tcc	2004-01-29 03:52:24.000000000 +0100
+++ libstdc++-v3/include/bits/locale_facets.tcc	2004-02-22 18:28:31.000000000 +0100
@@ -884,22 +884,13 @@
       _M_convert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
 		       _ValueT __v) const
       {
-	// Note: digits10 is rounded down: add 1 to ensure the maximum
-	// available precision.  Then, in general, one more 1 needs to
-	// be added since, when the %{g,G} conversion specifiers are
-	// chosen inside _S_format_float, the precision field is "the
-	// maximum number of significant digits", *not* the "number of
-	// digits to appear after the decimal point", as happens for
-	// %{e,E,f,F} (C99, 7.19.6.1,4).
-	const int __max_digits = numeric_limits<_ValueT>::digits10 + 2;
-
 	// Use default precision if out of range.
 	streamsize __prec = __io.precision();
-	if (__prec > static_cast<streamsize>(__max_digits))
-	  __prec = static_cast<streamsize>(__max_digits);
-	else if (__prec < static_cast<streamsize>(0))
+	if (__prec < static_cast<streamsize>(0))
 	  __prec = static_cast<streamsize>(6);
 
+	const int __max_digits = numeric_limits<_ValueT>::digits10;	
+
 	typedef numpunct<_CharT>  __facet_type;
 	typedef __locale_cache<numpunct<_CharT> > __cache_type;
 	const locale __loc = __io._M_getloc();
@@ -911,7 +902,7 @@
 	char __fbuf[16];
 
 #ifdef _GLIBCPP_USE_C99
-	// First try a buffer perhaps big enough (for sure sufficient
+	// First try a buffer perhaps big enough (most probably sufficient
 	// for non-ios_base::fixed outputs)
 	int __cs_size = __max_digits * 3;
 	char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
@@ -933,13 +924,13 @@
 	const bool __fixed = __io.flags() & ios_base::fixed;
 	const int __max_exp = numeric_limits<_ValueT>::max_exponent10;
 
-	// ios_base::fixed outputs may need up to __max_exp+1 chars
-	// for the integer part + up to __max_digits chars for the
-	// fractional part + 3 chars for sign, decimal point, '\0'. On
-	// the other hand, for non-fixed outputs __max_digits*3 chars
-	// are largely sufficient.
-	const int __cs_size = __fixed ? __max_exp + __max_digits + 4 
-	                              : __max_digits * 3;
+	// ios_base::fixed outputs may need up to __max_exp + 1 chars
+	// for the integer part + __prec chars for the fractional part
+	// + 3 chars for sign, decimal point, '\0'. On the other hand,
+	// for non-fixed outputs __max_digits * 2 chars + __prec are
+	// largely sufficient.
+	const int __cs_size = __fixed ? __max_exp + __prec + 4 
+	                              : __max_digits * 2 + __prec;
 	char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
 
 	_S_format_float(__io, __fbuf, __mod, __prec);

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