This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: libstdc++/3720: Problems with num_get
- From: Philip Martin <pmartin at uklinux dot net>
- To: bkoz at gcc dot gnu dot org
- Cc: gcc-bugs at gcc dot gnu dot org, gcc-gnats at gcc dot gnu dot org, gcc-prs at gcc dot gnu dot org, schmid at snake dot iap dot physik dot tu-darmstadt dot de
- Date: 07 Dec 2001 18:21:13 +0000
- Subject: Re: libstdc++/3720: Problems with num_get
- Envelope-to: gcc-prs@gcc.gnu.org
- References: <20011207091150.29549.qmail@sources.redhat.com>
bkoz@gcc.gnu.org writes:
> Synopsis: Problems with num_get
>
> State-Changed-From-To: analyzed->feedback
> State-Changed-By: bkoz
> State-Changed-When: Fri Dec 7 01:11:50 2001
> State-Changed-Why:
> Try this:
>
> 2001-12-06 Benjamin Kosnik <bkoz@redhat.com>
>
> libstdc++/3720
> * include/bits/locale_facets.tcc (num_put): Clean.
> (num_get::_M_extract_float): Change argument to string.
> (num_get::do_get(float)): Fixup.
> (num_get::do_get(double)): Same.
> (num_get::do_get(long double)): Same.
> (num_get::_M_extract_int): Add maximum length parameter, __max.
> (num_get::_M_extract_float): Correct zeros, use string.
> * include/bits/locale_facets.h (num_get::_M_extract_float): Change
> declaration here.
> * src/locale.cc (__num_base::_S_atoms): Remove x, X.
> * testsuite/27_io/istream_extractor_arith.cc (test13): Add.
>
> 2001-12-06 Philip Martin <pmartin@uklinux.net>
>
> * testsuite/27_io/istream_extractor_arith.cc
> (test12): Add
> tests for excess input digits.
>
>
> http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&pr=3720&database=gcc
1. Looking at the code, there are two calls to log() per integer
input in _M_extract_int() in locale_facets.tcc
// Figure out the maximum number of digits that can be extracted
// for the given type, using the determined base.
int __max_digits;
if (__base != 10)
__max_digits = static_cast<int>(ceil(__max * log(10.0)
/log(static_cast<double>(__base))));
else
__max_digits = __max;
All standard input is in base 8, 10, or 16, so how about something
based on
if (__base == 10)
__max_digits = __max;
else if (__base == 8)
__max_digits = 1 + __max * 11073 / 10000; // approx. log(10)/log(8)
else if (__base == 16)
__max_digits = 1 + __max * 8305 / 10000; // approx. log(10)/log(16)
else
???
I haven't fully checked if this is accurate enough, however with
the truncation to an int no great accuracy is required.
2. You aren't calling test13() from main() in
testsuite/27_io/istream_extractor_arith.cc
3. Trying the code, input of std::numeric_limits<T>::max() in octal or
hex doesn't appear to work for integers, e.g. reading 017777777777
into a long on x86 doesn't work, it appears to accept one character
too few. Decimal works.
Philip