Date: Mon, 24 Nov 1997 13:38:22 +0200 (IST) From: Eli Zaretskii To: Morten Welinder cc: djgpp-workers AT delorie DOT com, DJ Delorie Subject: Re: strtod.c In-Reply-To: <9611150426.AA14339@robbie.rentec.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Precedence: bulk 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 #include + #include + #include #include 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 + + 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