Mail Archives: djgpp-workers/1997/11/24/06:38:50
On Thu, 14 Nov 1996 (YES, A YEAR AGO!), Morten Welinder wrote:
> Just took a look at strtod.c. From inspection it looks like
> a number like "0e2000000000" would take close to forever to
> convert.
> ...and while I am at it: strtod.txh does not mention that the
> second parameter may be zero.
Well, here's what I think Morten had in mind. Morten, can you look at
this please? (The docs of strtol is also corrected.)
*** src/libc/ansi/stdlib/strtod.c~0 Sun Sep 1 00:39:14 1996
--- src/libc/ansi/stdlib/strtod.c Fri Nov 21 20:22:58 1997
***************
*** 1,7 ****
--- 1,10 ----
+ /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
#include <math.h>
#include <stdlib.h>
+ #include <float.h>
+ #include <errno.h>
#include <libc/unconst.h>
double
***************
*** 52,58 ****
}
}
! if (flags == 0)
{
if (sret)
*sret = unconst(s, char *);
--- 55,61 ----
}
}
! if (flags == 0 || r == 0)
{
if (sret)
*sret = unconst(s, char *);
***************
*** 84,97 ****
}
}
! if (esign < 0)
for (i = 1; i <= e; i++)
r *= 0.1L;
else
for (i = 1; i <= e; i++)
r *= 10.0;
if (sret)
*sret = unconst(s, char *);
return r * sign;
}
--- 87,148 ----
}
}
! /* Detect overflow. */
! if (e < 0)
! {
! errno = ERANGE;
! r = HUGE_VAL;
! }
! else if (esign < 0)
for (i = 1; i <= e; i++)
r *= 0.1L;
else
for (i = 1; i <= e; i++)
+ {
r *= 10.0;
+ if (r > DBL_MAX) /* detect overflow */
+ {
+ errno = ERANGE;
+ r = HUGE_VAL;
+ break;
+ }
+ }
if (sret)
*sret = unconst(s, char *);
return r * sign;
}
+
+ #ifdef TEST
+
+ #include <stdio.h>
+
+ static char *testnum[] = {
+ "0e20",
+ "1e200",
+ "0e2000000000", /* suggested by Morten Welinder */
+ "1e6000000000", /* overflow */
+ "1e400", /* ditto */
+ 0
+ };
+
+ int main (void)
+ {
+ int i;
+
+ errno = 0;
+
+ for (i = 0; testnum[i]; i++)
+ {
+ printf ("%s gives %20.15g\n", testnum[i], strtod (testnum[i], (char **)0));
+ if (errno)
+ {
+ perror ("strtod");
+ errno = 0;
+ }
+ }
+
+ return 0;
+ }
+
+ #endif
*** src/libc/ansi/stdlib/strtod.t~0 Mon Jul 10 05:39:58 1995
--- src/libc/ansi/stdlib/strtod.txh Fri Nov 21 20:45:28 1997
***************
*** 9,21 ****
@subheading Description
! This function converts as many characters of @var{s} that look like a
! floating point number into one, and sets @var{*endp} to point to the
! first unused character.
@subheading Return Value
! The value the string represented.
@subheading Example
--- 9,27 ----
@subheading Description
! This function converts as many characters of @var{s} as look like a
! floating point number into that number. If @var{endp} is not a null
! pointer, @code{*endp} is set to point to the first unconverted
! character.
@subheading Return Value
! The value the represented by @var{s}.
!
! If a number represented by @var{s} doesn't fit into the range of values
! representable by the type @code{double}, the function returns either
! @code{-HUGE_VAL} (if @var{s} begins with the character @code{-}) or
! @code{+HUGE_VAL}, and sets @code{errno} to @code{ERANGE}.
@subheading Example
*** src/libc/ansi/stdlib/strtol.t~0 Mon Jul 10 05:39:58 1995
--- src/libc/ansi/stdlib/strtol.txh Fri Nov 21 20:36:02 1997
***************
*** 10,17 ****
@subheading Description
This function converts as much of @var{s} as looks like an appropriate
! number into the value of that number, and sets @var{*endp} to point to
! the first unused character.
The @var{base} argument indicates what base the digits (or letters)
should be treated as. If @var{base} is zero, the base is determined by
--- 10,17 ----
@subheading Description
This function converts as much of @var{s} as looks like an appropriate
! number into the value of that number. If @var{endp} is not a null
! pointer, @var{*endp} is set to point to the first unused character.
The @var{base} argument indicates what base the digits (or letters)
should be treated as. If @var{base} is zero, the base is determined by
- Raw text -