Mail Archives: djgpp-workers/2002/12/18/09:37:34
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 -