fix strtod("-0x",NULL)

Jeff Johnston jjohnstn@redhat.com
Thu Feb 21 22:17:00 GMT 2008


Thanks Eric.  Feel free to commit this.

-- Jeff J.

Eric Blake wrote:
> strtod is required to parse out the longest sequence of the expected form.  
> Since "-0x" is not a valid hex constant, strtod should fall back and parse the 
> valid "-0" as -0.0, rather than claiming that the input is invalid and 
> returning +0.0.  OK to apply?
>
> [Also, strtof() currently suffers from a double rounding bug - there are some 
> decimal values which round once in conversion to double, then round again in 
> conversion to float, resulting in a float that is further away from the 
> original decimal value than if you had gone straight to float - but I am not in 
> the mood to fix that, as it is a much more difficult problem.]
>
> 2008-02-20  Eric Blake  <ebb9@byu.net>
>
> 	Fix strtod("-0x", NULL).
> 	* libc/stdlib/strtod.c (_strtod_r): Fall back to 0 if hex parse
> 	fails.
>
> Index: libc/stdlib/strtod.c
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/stdlib/strtod.c,v
> retrieving revision 1.9
> diff -u -p -r1.9 strtod.c
> --- libc/stdlib/strtod.c        31 Aug 2007 21:21:27 -0000      1.9
> +++ libc/stdlib/strtod.c        20 Feb 2008 20:56:02 -0000
> @@ -37,12 +37,19 @@ DESCRIPTION
>         producing a substring which can be converted to a double
>         value.  The substring converted is the longest initial
>         subsequence of <[str]>, beginning with the first
> -       non-whitespace character, that has the format:
> -       .[+|-]<[digits]>[.][<[digits]>][(e|E)[+|-]<[digits]>] 
> +       non-whitespace character, that has one of these formats:
> +       .[+|-]<[digits]>[.[<[digits]>]][(e|E)[+|-]<[digits]>]
> +       .[+|-].<[digits]>[(e|E)[+|-]<[digits]>]
> +       .[+|-](i|I)(n|N)(f|F)[(i|I)(n|N)(i|I)(t|T)(y|Y)]
> +       .[+|-](n|N)(a|A)(n|N)[<(>[<[hexdigits]>]<)>]
> +       .[+|-]0(x|X)<[hexdigits]>[.[<[hexdigits]>]][(p|P)[+|-]<[digits]>]
> +       .[+|-]0(x|X).<[hexdigits]>[(p|P)[+|-]<[digits]>]
>         The substring contains no characters if <[str]> is empty, consists
>         entirely of whitespace, or if the first non-whitespace
>         character is something other than <<+>>, <<->>, <<.>>, or a
> -       digit. If the substring is empty, no conversion is done, and
> +       digit, and cannot be parsed as infinity or NaN. If the platform
> +       does not support NaN, then NaN is treated as an empty substring.
> +       If the substring is empty, no conversion is done, and
>         the value of <[str]> is stored in <<*<[tail]>>>.  Otherwise,
>         the substring is converted, and a pointer to the final string
>         (which will contain at least the terminating null character of
> @@ -52,7 +59,8 @@ DESCRIPTION
>  
>         This implementation returns the nearest machine number to the
>         input decimal string.  Ties are broken by using the IEEE
> -       round-even rule.
> +       round-even rule.  However, strtof is currently subject to double
> +       rounding errors.
>  
>         The alternate function <<_strtod_r>> is a reentrant version.
>         The extra argument <[reent]> is a pointer to a reentrancy structure.
> @@ -254,6 +262,9 @@ _DEFUN (_strtod_r, (ptr, s00, se),
>                 switch(s[1]) {
>                   case 'x':
>                   case 'X':
> +                       /* If the number is not hex, then the parse of
> +                           0 is still valid.  */
> +                       s00 = s + 1;
>                         {
>  #if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && 
> defined(FE_UPWARD)
>                         FPI fpi1 = fpi;
> @@ -268,7 +279,6 @@ _DEFUN (_strtod_r, (ptr, s00, se),
>                         switch((i = gethex(ptr, &s, &fpi1, &exp, &bb, sign)) & S
> TRTOG_Retmask) {
>                           case STRTOG_NoNumber:
>                                 s = s00;
> -                               sign = 0;
>                           case STRTOG_Zero:
>                                 break;
>                           default:
>
>
>
>   



More information about the Newlib mailing list