delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1997/11/24/06:38:50

Date: Mon, 24 Nov 1997 13:38:22 +0200 (IST)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
To: Morten Welinder <terra AT diku DOT dk>
cc: djgpp-workers AT delorie DOT com, DJ Delorie <dj AT delorie DOT com>
Subject: Re: strtod.c
In-Reply-To: <9611150426.AA14339@robbie.rentec.com>
Message-ID: <Pine.SUN.3.91.971124133538.23713X-100000@is>
MIME-Version: 1.0

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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019