This is the mail archive of the mailing list for the newlib 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]

fix strtod("-0x",NULL)

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  <>

	Fix strtod("-0x", NULL).
	* libc/stdlib/strtod.c (_strtod_r): Fall back to 0 if hex parse

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) && 
                        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:

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