delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2002/12/18/09:37:34

Date: Wed, 18 Dec 2002 14:37:49 +0000
From: "Richard Dawe" <rich AT phekda DOT freeserve DOT co DOT uk>
Sender: rich AT phekda DOT freeserve DOT co DOT uk
To: djgpp-workers AT delorie DOT com
X-Mailer: Emacs 21.3.50 (via feedmail 8.3.emacs20_6 I) and Blat ver 1.8.6
Subject: strtof, revision 2 (C99) [PATCH]
Message-Id: <E18OfK8-0000k0-00@phekda.freeserve.co.uk>
Reply-To: djgpp-workers AT delorie DOT com

Hello.

Below is revision 2 of the strtof patch. This updates the test
to test NaNs too - they're not understood by strto*.

Here's what the test displays for me now:

float tests:
Test 1: 2 -> 2
Test 2: 20 -> 20
Test 3: 200 -> 200
Test 4: 2e+38 -> 2e+38
Test 5: 1e+38 -> 1e+38
Test 6: Inf -> 0
Test 7: 0.2 -> 0.2
Test 8: 0.02 -> 0.02
Test 9: 0.002 -> 0.002
Test 10: 2e-37 -> 2e-37
Test 11: 2e-38 -> 2e-38
Test 12: 2e-39 -> 2e-39
Test 13: 9.80909e-45 -> 9.80909e-45
Test 14: 1.4013e-45 -> 1.4013e-45
float_t tests:
Test 1: Inf -> 0
Test 2: NaN -> 0

OK to commit?

Thanks, bye, Rich =]

Index: include/stdlib.h
===================================================================
RCS file: /cvs/djgpp/djgpp/include/stdlib.h,v
retrieving revision 1.15
diff -p -c -3 -r1.15 stdlib.h
*** include/stdlib.h	6 Dec 2002 09:32:41 -0000	1.15
--- include/stdlib.h	18 Dec 2002 14:32:29 -0000
*************** int	rand(void);
*** 72,77 ****
--- 72,78 ----
  void *	realloc(void *_ptr, size_t _size);
  void	srand(unsigned _seed);
  double	strtod(const char *_s, char **_endptr);
+ float	strtof(const char *_s, char **_endptr);
  long	strtol(const char *_s, char **_endptr, int _base);
  long double	strtold(const char *_s, char **_endptr);
  unsigned long	strtoul(const char *_s, char **_endptr, int _base);
Index: src/libc/c99/stdlib/makefile
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/c99/stdlib/makefile,v
retrieving revision 1.1
diff -p -c -3 -r1.1 makefile
*** src/libc/c99/stdlib/makefile	30 Nov 2002 09:27:03 -0000	1.1
--- src/libc/c99/stdlib/makefile	18 Dec 2002 14:32:29 -0000
***************
*** 2,6 ****
--- 2,7 ----
  TOP=../..
  
  SRC += _exit.S
+ SRC += strtof.c
  
  include $(TOP)/../makefile.inc
Index: src/docs/kb/wc204.txi
===================================================================
RCS file: /cvs/djgpp/djgpp/src/docs/kb/wc204.txi,v
retrieving revision 1.130
diff -p -c -3 -r1.130 wc204.txi
*** src/docs/kb/wc204.txi	18 Dec 2002 07:29:44 -0000	1.130
--- src/docs/kb/wc204.txi	18 Dec 2002 14:32:38 -0000
*************** to avoid conflicts.
*** 833,835 ****
--- 833,838 ----
  @findex ctime AT r{, and calls to @code{getenv}}
  Fix caching when environment variable TZ is not set.  Prevents many calls to
  getenv() which are not needed.
+ 
+ @findex strtof
+ The function @code{strtof} was added.
Index: tests/libc/c99/stdlib/makefile
===================================================================
RCS file: /cvs/djgpp/djgpp/tests/libc/c99/stdlib/makefile,v
retrieving revision 1.1
diff -p -c -3 -r1.1 makefile
*** tests/libc/c99/stdlib/makefile	30 Nov 2002 09:28:09 -0000	1.1
--- tests/libc/c99/stdlib/makefile	18 Dec 2002 14:32:38 -0000
***************
*** 1,5 ****
--- 1,6 ----
  TOP=../..
  
  SRC += t-_exit.c
+ SRC += t-strtof.c
  
  include $(TOP)/../makefile.inc
*** /dev/null	Wed Dec 18 14:33:45 2002
--- src/libc/c99/stdlib/strtof.c	Tue Dec 17 13:05:26 2002
***************
*** 0 ****
--- 1,126 ----
+ /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
+ /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
+ /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
+ /* 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 <ctype.h>
+ #include <libc/unconst.h>
+ 
+ float
+ strtof(const char *s, char **sret)
+ {
+   long double r;		/* result */
+   int e;			/* exponent */
+   long double d;		/* scale */
+   int sign;			/* +- 1.0 */
+   int esign;
+   int i;
+   int flags=0;
+ 
+   r = 0.0;
+   sign = 1;
+   e = 0;
+   esign = 1;
+ 
+   if (sret)
+     *sret = unconst(s, char *);
+ 
+   while (isspace((unsigned char) *s))
+     s++;
+ 
+   if (*s == '+')
+     s++;
+   else if (*s == '-')
+   {
+     sign = -1;
+     s++;
+   }
+ 
+   while ((*s >= '0') && (*s <= '9'))
+   {
+     flags |= 1;
+     r *= 10.0;
+     r += *s - '0';
+     s++;
+   }
+ 
+   if (*s == '.')
+   {
+     d = 0.1L;
+     s++;
+     while ((*s >= '0') && (*s <= '9'))
+     {
+       flags |= 2;
+       r += d * (*s - '0');
+       s++;
+       d *= 0.1L;
+     }
+   }
+ 
+   if (flags == 0)
+     return 0;
+ 
+   if (sret)
+     *sret = unconst(s, char *);
+ 
+   if ((*s == 'e') || (*s == 'E'))
+   {
+     s++;
+     if (*s == '+')
+       s++;
+     else if (*s == '-')
+     {
+       s++;
+       esign = -1;
+     }
+     if ((*s < '0') || (*s > '9'))
+       return r * sign;
+ 
+     while ((*s >= '0') && (*s <= '9'))
+     {
+       e *= 10;
+       e += *s - '0';
+       s++;
+     }
+   }
+ 
+   /* Detect overflow.  */
+   if (e < 0)
+   {
+     errno = ERANGE;
+     r = HUGE_VAL;
+   }
+   else if (esign < 0)
+     for (i = 1; i <= e; i++)
+     {
+       r *= 0.1L;
+       /* Detect underflow below 2^-150, which is half
+          the smallest representable float. */
+       if (r < 7.00649232162408535461e-46L)
+       {
+ 	errno = ERANGE;
+ 	r = 0.0;
+ 	break;
+       }
+     }
+   else
+     for (i = 1; i <= e; i++)
+     {
+       r *= 10.0;
+       if (r > FLT_MAX)	/* detect overflow */
+       {
+ 	errno = ERANGE;
+ 	r = HUGE_VAL;
+ 	break;
+       }
+     }
+ 
+   if (sret)
+     *sret = unconst(s, char *);
+   return r * sign;
+ }
*** /dev/null	Wed Dec 18 14:33:45 2002
--- src/libc/c99/stdlib/strtof.txh	Sat Dec 14 22:30:10 2002
***************
*** 0 ****
--- 1,36 ----
+ @node strtof, string
+ @subheading Syntax
+ 
+ @example
+ #include <stdlib.h>
+ 
+ float strtof(const char *s, char **endp);
+ @end example
+ 
+ @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 Portability
+ 
+ @portability !ansi-c89, ansi-c99, !posix-1003.2-1992, posix-1003.1-2001
+ 
+ @subheading Example
+ 
+ @example
+ char *buf = "123ret";
+ char *bp;
+ float x = strtof(buf, &bp);
+ @end example
*** /dev/null	Wed Dec 18 14:33:45 2002
--- tests/libc/c99/stdlib/t-strtof.c	Wed Dec 18 14:27:42 2002
***************
*** 0 ****
--- 1,56 ----
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <libc/ieee.h>
+ 
+ /* float tests */
+ static const float tests[] = {
+   2.0, 20.0, 200.0, 2e38, 1e38,
+   2.0e39, /* Larger than maximum float => "infinite" */
+   2.0e-01, 2.0e-02, 2.0e-03, 2e-37,
+   2e-38, 2e-39,
+   1e-44, 1e-45
+ };
+ 
+ static const size_t n_tests = sizeof(tests) / sizeof(tests[0]);
+ 
+ /* float_t tests - so we can specify *exactly* what we want. */
+ static const float_t tests2[] = {
+   /* Infinity */
+   { 0U, 0xffU, 0x0 },
+ 
+   /* NaN */
+   { 1U, 0xffU, 0x0 }
+ };
+ 
+ static const size_t n_tests2 = sizeof(tests2) / sizeof(tests2[0]);
+ 
+ static void inline
+ result (const size_t n, const float f_in, const float f_out)
+ {
+   printf("Test %lu: %g -> %g\n", n, f_in, f_out);
+ }
+ 
+ int
+ main (void)
+ {
+   char buf[128];
+   float f_res;
+   size_t i;
+ 
+   puts("float tests:");
+   for (i = 0; i < n_tests; i++) {
+     sprintf(buf, "%g", tests[i]);
+     f_res = strtof(buf, NULL);
+     result(i + 1, tests[i], f_res);
+   }
+ 
+   puts("float_t tests:");
+   for (i = 0; i < n_tests2; i++) {
+     sprintf(buf, "%g", *(const float *) &tests2[i]);
+     f_res = strtof(buf, NULL);
+     result(i + 1, *(const float *) &tests2[i], f_res);
+   }
+ 
+   return(EXIT_SUCCESS);
+ }

- Raw text -


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