Date: Mon, 20 Jan 2003 17:44:46 +0000 From: "Richard Dawe" 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 & HUGE_VALF [PATCH] Message-Id: Reply-To: djgpp-workers AT delorie DOT com Hello. As promised, there is a patch to fix strtof below. This introduces HUGE_VALF and HUGE_VALL. It also includes some new test cases for strtof. In strtof I added an extra flag to indicate overflow, to avoid any floating-point comparisons in the overflow case, where we return HUGE_VALF. Perhaps we could store HUGE_VALF in a "long double", but I wasn't sure whether: (float)(long double) HUGE_VALF == HUGE_VALF OK to commit? Thanks, bye, Rich =] Index: include/math.h =================================================================== RCS file: /cvs/djgpp/djgpp/include/math.h,v retrieving revision 1.5 diff -p -c -3 -r1.5 math.h *** include/math.h 4 Aug 1999 19:54:59 -0000 1.5 --- include/math.h 20 Jan 2003 17:39:07 -0000 *************** *** 1,3 **** --- 1,4 ---- + /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ *************** extern "C" { *** 14,21 **** #ifndef __dj_ENFORCE_ANSI_FREESTANDING ! extern double __dj_huge_val; #define HUGE_VAL __dj_huge_val double acos(double _x); double asin(double _x); --- 15,27 ---- #ifndef __dj_ENFORCE_ANSI_FREESTANDING ! extern double __dj_huge_val; ! extern float __dj_huge_valf; ! extern long double __dj_huge_vall; ! #define HUGE_VAL __dj_huge_val + #define HUGE_VALF __dj_huge_valf + #define HUGE_VALL __dj_huge_vall double acos(double _x); double asin(double _x); Index: src/libc/c99/stdlib/strtof.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/c99/stdlib/strtof.c,v retrieving revision 1.1 diff -p -c -3 -r1.1 strtof.c *** src/libc/c99/stdlib/strtof.c 8 Jan 2003 20:16:07 -0000 1.1 --- src/libc/c99/stdlib/strtof.c 20 Jan 2003 17:39:07 -0000 *************** *** 1,3 **** --- 1,4 ---- + /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */ /* 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 */ *************** strtof(const char *s, char **sret) *** 21,26 **** --- 22,28 ---- int esign; int i; int flags=0; + int overflow=0; r = 0.0; sign = 1; *************** strtof(const char *s, char **sret) *** 93,99 **** if (e < 0) { errno = ERANGE; ! r = HUGE_VAL; } else if (esign < 0) for (i = 1; i <= e; i++) --- 95,102 ---- if (e < 0) { errno = ERANGE; ! r = 0.0; ! overflow = 1; } else if (esign < 0) for (i = 1; i <= e; i++) *************** strtof(const char *s, char **sret) *** 115,126 **** if (r > FLT_MAX) /* detect overflow */ { errno = ERANGE; ! r = HUGE_VAL; break; } } if (sret) *sret = unconst(s, char *); ! return r * sign; } --- 118,134 ---- if (r > FLT_MAX) /* detect overflow */ { errno = ERANGE; ! r = 0; ! overflow = 1; break; } } if (sret) *sret = unconst(s, char *); ! ! if (!overflow) ! return r * sign; ! else ! return HUGE_VALF * sign; } Index: src/libc/c99/stdlib/strtof.txh =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/c99/stdlib/strtof.txh,v retrieving revision 1.2 diff -p -c -3 -r1.2 strtof.txh *** src/libc/c99/stdlib/strtof.txh 11 Jan 2003 10:20:45 -0000 1.2 --- src/libc/c99/stdlib/strtof.txh 20 Jan 2003 17:39:10 -0000 *************** The value the represented by @var{s}. *** 20,27 **** If a number represented by @var{s} doesn't fit into the range of values representable by the type @code{float}, 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 --- 20,27 ---- If a number represented by @var{s} doesn't fit into the range of values representable by the type @code{float}, the function returns either ! @code{-HUGE_VALF} (if @var{s} begins with the character @code{-}) or ! @code{+HUGE_VALF}, and sets @code{errno} to @code{ERANGE}. @subheading Portability Index: src/docs/kb/wc204.txi =================================================================== RCS file: /cvs/djgpp/djgpp/src/docs/kb/wc204.txi,v retrieving revision 1.133 diff -p -c -3 -r1.133 wc204.txi *** src/docs/kb/wc204.txi 19 Jan 2003 13:04:31 -0000 1.133 --- src/docs/kb/wc204.txi 20 Jan 2003 17:39:15 -0000 *************** The function @code{strtof} was added. *** 840,842 **** --- 840,847 ---- @findex strlcat @findex strlcpy The functions @code{strlcat} and @code{strlcpy} were added. + + @cindex C99 compliance, mathematics + @vindex HUGE_VALF + @vindex HUGE_VALL + The constants @code{HUGE_VALF} and @code{HUGE_VALL} were added. Index: tests/libc/c99/stdlib/t-strtof.c =================================================================== RCS file: /cvs/djgpp/djgpp/tests/libc/c99/stdlib/t-strtof.c,v retrieving revision 1.1 diff -p -c -3 -r1.1 t-strtof.c *** tests/libc/c99/stdlib/t-strtof.c 8 Jan 2003 20:18:48 -0000 1.1 --- tests/libc/c99/stdlib/t-strtof.c 20 Jan 2003 17:39:18 -0000 *************** *** 1,3 **** --- 1,5 ---- + #include + #include #include #include #include *************** static const float_t tests2[] = { *** 25,30 **** --- 27,56 ---- static const size_t n_tests2 = sizeof(tests2) / sizeof(tests2[0]); + typedef struct { + const long double *ld; + const int sign; + const char *str; + const int overflow; + } test3_t; + + static long double ld_float_max; + static long double ld_float_max_10; + static long double ld_double_max; + + static const test3_t tests3[] = { + { &ld_float_max, 1, "FLT_MAX", 0 }, + { &ld_float_max, -1, "-FLT_MAX", 0 }, + { &ld_float_max_10, 1, "FLT_MAX * 10", 1 }, + { &ld_float_max_10, -1, "-FLT_MAX * 10", 1 }, + { &ld_double_max, 1, "DBL_MAX", 1 }, + { &ld_double_max, -1, "-DBL_MAX", 1 }, + { &__dj_long_double_max, 1, "LDBL_MAX", 1 }, + { &__dj_long_double_max, -1, "-LDBL_MAX", 1 } + }; + + static const size_t n_tests3 = sizeof(tests3) / sizeof(tests3[0]); + static void inline result (const size_t n, const float f_in, const float f_out) { *************** main (void) *** 36,43 **** --- 62,74 ---- { char buf[128]; float f_res; + int eq; size_t i; + ld_float_max = __dj_float_max; + ld_float_max_10 = ld_float_max * 10; + ld_double_max = __dj_double_max; + puts("float tests:"); for (i = 0; i < n_tests; i++) { sprintf(buf, "%g", tests[i]); *************** main (void) *** 50,55 **** --- 81,110 ---- sprintf(buf, "%g", *(const float *) &tests2[i]); f_res = strtof(buf, NULL); result(i + 1, *(const float *) &tests2[i], f_res); + } + + puts("HUGE_VALF tests:"); + for (i = 0; i < n_tests3; i++) { + sprintf(buf, "%Lg", *(tests3[i].ld) * tests3[i].sign); + f_res = strtof(buf, NULL); + + printf("strtof(sprintf(..., %s)) == %sHUGE_VALF: ", + tests3[i].str, + (tests3[i].sign < 0) ? "-" : ""); + + eq = (f_res == (HUGE_VALF * ((tests3[i].sign < 0) ? -1 : 1))); + + if (tests3[i].overflow) { + if (eq) + puts("Yes - OK"); + else + puts("No - FAIL"); + } else { + if (eq) + puts("Yes - FAIL"); + else + puts("No - OK"); + } } return(EXIT_SUCCESS); --- /dev/null 2003-01-20 17:41:17.000000000 +0000 +++ src/libc/c99/math/.cvsignore 2002-12-16 19:03:52.000000000 +0000 @@ -0,0 +1,3 @@ +*.d +*.oh + --- /dev/null 2003-01-20 17:41:17.000000000 +0000 +++ src/libc/c99/math/makefile 2002-12-16 19:04:22.000000000 +0000 @@ -0,0 +1,7 @@ +# Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details +TOP=../.. + +SRC += hugevalf.c +SRC += hugevall.c + +include $(TOP)/../makefile.inc --- /dev/null 2003-01-20 17:41:17.000000000 +0000 +++ src/libc/c99/math/hugevalf.c 2003-01-20 17:06:52.000000000 +0000 @@ -0,0 +1,4 @@ +/* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */ +#include + +float_t __dj_huge_valf = { 0x00000, 0xff, 0x0 }; --- /dev/null 2003-01-20 17:41:17.000000000 +0000 +++ src/libc/c99/math/hugevall.c 2003-01-20 17:06:58.000000000 +0000 @@ -0,0 +1,4 @@ +/* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */ +#include + +long_double_t __dj_huge_vall = { 0x00000000, 0x00000000, 0x7fff, 0x0 };