Commit 7c9b102e by Paolo Carlini Committed by Paolo Carlini

re PR libstdc++/14220 ([3.5] num_put::do_put() undesired float/double behavior)

2004-07-29  Paolo Carlini  <pcarlini@suse.de>

	PR libstdc++/14220
	* include/bits/locale_facets.tcc (num_put<>::_M_insert_float):
	Don't clip the precision passed down to __convert_from_v:
	22.2.2.2.2 nowhere says so.
	* testsuite/22_locale/num_put/put/char/14220.cc: New.
	* testsuite/22_locale/num_put/put/wchar_t/14220.c: Likewise.

From-SVN: r85315
parent 118a8d02
2004-07-29 Paolo Carlini <pcarlini@suse.de> 2004-07-29 Paolo Carlini <pcarlini@suse.de>
PR libstdc++/14220
* include/bits/locale_facets.tcc (num_put<>::_M_insert_float):
Don't clip the precision passed down to __convert_from_v:
22.2.2.2.2 nowhere says so.
* testsuite/22_locale/num_put/put/char/14220.cc: New.
* testsuite/22_locale/num_put/put/wchar_t/14220.c: Likewise.
2004-07-29 Paolo Carlini <pcarlini@suse.de>
* docs/html/ext/lwg-active.html, lwg-defects.html: Import Revision 31. * docs/html/ext/lwg-active.html, lwg-defects.html: Import Revision 31.
2004-07-29 Paolo Carlini <pcarlini@suse.de> 2004-07-29 Paolo Carlini <pcarlini@suse.de>
......
...@@ -1052,29 +1052,20 @@ namespace std ...@@ -1052,29 +1052,20 @@ namespace std
const locale& __loc = __io._M_getloc(); const locale& __loc = __io._M_getloc();
const __cache_type* __lc = __uc(__loc); const __cache_type* __lc = __uc(__loc);
// 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. // Use default precision if out of range.
streamsize __prec = __io.precision(); streamsize __prec = __io.precision();
if (__prec > static_cast<streamsize>(__max_digits)) if (__prec < static_cast<streamsize>(0))
__prec = static_cast<streamsize>(__max_digits);
else if (__prec < static_cast<streamsize>(0))
__prec = static_cast<streamsize>(6); __prec = static_cast<streamsize>(6);
const int __max_digits = numeric_limits<_ValueT>::digits10;
// [22.2.2.2.2] Stage 1, numeric conversion to character. // [22.2.2.2.2] Stage 1, numeric conversion to character.
int __len; int __len;
// Long enough for the max format spec. // Long enough for the max format spec.
char __fbuf[16]; char __fbuf[16];
#ifdef _GLIBCXX_USE_C99 #ifdef _GLIBCXX_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) // for non-ios_base::fixed outputs)
int __cs_size = __max_digits * 3; int __cs_size = __max_digits * 3;
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
...@@ -1097,13 +1088,13 @@ namespace std ...@@ -1097,13 +1088,13 @@ namespace std
const int __max_exp = numeric_limits<_ValueT>::max_exponent10; const int __max_exp = numeric_limits<_ValueT>::max_exponent10;
// The size of the output string is computed as follows. // The size of the output string is computed as follows.
// ios_base::fixed outputs may need up to __max_exp+1 chars // ios_base::fixed outputs may need up to __max_exp + 1 chars
// for the integer part + up to __max_digits chars for the // for the integer part + __prec chars for the fractional part
// fractional part + 3 chars for sign, decimal point, '\0'. On // + 3 chars for sign, decimal point, '\0'. On the other hand,
// the other hand, for non-fixed outputs __max_digits*3 chars // for non-fixed outputs __max_digits * 2 + __prec chars are
// are largely sufficient. // largely sufficient.
const int __cs_size = __fixed ? __max_exp + __max_digits + 4 const int __cs_size = __fixed ? __max_exp + __prec + 4
: __max_digits * 3; : __max_digits * 2 + __prec;
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
__num_base::_S_format_float(__io, __fbuf, __mod); __num_base::_S_format_float(__io, __fbuf, __mod);
......
// 2004-04-30 Paolo Carlini <pcarlini@suse.de>
// Copyright (C) 2004 Free Software Foundation
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 22.2.2.2.1 num_put members
#include <locale>
#include <sstream>
#include <testsuite_hooks.h>
// libstdc++/14220
void test01()
{
using namespace std;
bool test __attribute__((unused)) = true;
ostringstream oss;
const num_put<char>& np = use_facet<num_put<char> >(oss.getloc());
const int precision = 1000;
oss.precision(precision);
oss.setf(ios_base::fixed);
np.put(oss.rdbuf(), oss, '+', 1.0);
const string result = oss.str();
VERIFY( result.size() == precision + 2 );
}
int main()
{
test01();
return 0;
}
// 2004-04-30 Paolo Carlini <pcarlini@suse.de>
// Copyright (C) 2004 Free Software Foundation
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 22.2.2.2.1 num_put members
#include <locale>
#include <sstream>
#include <testsuite_hooks.h>
// libstdc++/14220
void test01()
{
using namespace std;
bool test __attribute__((unused)) = true;
wostringstream oss;
const num_put<wchar_t>& np = use_facet<num_put<wchar_t> >(oss.getloc());
const int precision = 1000;
oss.precision(precision);
oss.setf(ios_base::fixed);
np.put(oss.rdbuf(), oss, L'+', 1.0);
const wstring result = oss.str();
VERIFY( result.size() == precision + 2 );
}
int main()
{
test01();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment