This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
fix strtod("-0x",NULL)
- From: Eric Blake <ebb9 at byu dot net>
- To: newlib at sources dot redhat dot com
- Date: Wed, 20 Feb 2008 21:07:50 +0000 (UTC)
- Subject: 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 <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: