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++/3720: Problems with num_get


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



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