From: Message-Id: <200302261837.h1QIbPN04902@speedy.ludd.luth.se> Subject: strtod.c: inf and nan support To: DJGPP-WORKERS Date: Wed, 26 Feb 2003 19:37:25 +0100 (CET) X-Mailer: ELM [version 2.4ME+ PL78 (25)] MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=US-ASCII X-MailScanner: Found to be clean Reply-To: djgpp-workers AT delorie DOT com Hello. Here's what I've cooked up for supporting inf and nan in strtod.c. When we're happt with this one I'll take care of strtof() and strtold(). Right, MartinS New file, djgpp/src/libc/c99/math/nan.c: /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */ #include float_t __dj_nan = { 0x7fffff, 0xff, 0x0 }; Patch: Index: djgpp/include/math.h =================================================================== RCS file: /cvs/djgpp/djgpp/include/math.h,v retrieving revision 1.7 diff -p -u -r1.7 math.h --- djgpp/include/math.h 20 Feb 2003 19:04:02 -0000 1.7 +++ djgpp/include/math.h 26 Feb 2003 18:26:53 -0000 @@ -51,6 +51,11 @@ extern long double __dj_huge_vall; #define HUGE_VALF __dj_huge_valf #define HUGE_VALL __dj_huge_vall +#define INFINITY HUGE_VALF + +extern float __dj_nan; +#define NAN __dj_nan + #endif /* (__STDC_VERSION__ >= 199901L) || !__STRICT_ANSI__ */ #ifndef __STRICT_ANSI__ Index: djgpp/src/libc/ansi/stdlib/strtod.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/ansi/stdlib/strtod.c,v retrieving revision 1.5 diff -p -u -r1.5 strtod.c --- djgpp/src/libc/ansi/stdlib/strtod.c 17 Oct 2002 23:00:24 -0000 1.5 +++ djgpp/src/libc/ansi/stdlib/strtod.c 26 Feb 2003 18:26:56 -0000 @@ -8,6 +8,7 @@ #include #include #include +#include #include double @@ -32,6 +33,7 @@ strtod(const char *s, char **sret) while (isspace((unsigned char) *s)) s++; + /* Handle leading sign. */ if (*s == '+') s++; else if (*s == '-') @@ -40,6 +42,65 @@ strtod(const char *s, char **sret) s++; } + /* Handle INF and INFINITY. */ + if ( ! strnicmp( "INF", s, 3 ) ) + { + if( sret ) + { + if ( ! strnicmp( "INITY", &s[3], 5 ) ) + { + *sret = unconst((&s[8]), char *); + } + else + { + *sret = unconst((&s[3]), char *); + } + } + + if( 0 <= sign ) + { + return INFINITY; + } + else + { + return -INFINITY; + } + } + + /* Handle NAN and NAN(). */ + if ( ! strnicmp( "NAN", s, 3 ) ) + { + if( s[3] == '(' ) + { + int end_of_n_char_sequence = 4; + + while( s[end_of_n_char_sequence] != 0 && + s[end_of_n_char_sequence] != ')' ) + { + end_of_n_char_sequence++; + } + if( s[end_of_n_char_sequence] == ')' ) + { + /* If we are going to support "nan(0x1234) for setting specific bits, + * that code goes here. Something like "bits = strtoul( &s[4], &end_p, + * 0);". + */ + if( sret ) + { + *sret = unconst((&s[end_of_n_char_sequence+1]), char *); + return NAN; + } + } + /* The subject sequence didn't match NAN(), so match only NAN. */ + } + if( sret ) + { + *sret = unconst((&s[3]), char *); + } + return NAN; + } + + /* Handle ordinary numbers. */ while ((*s >= '0') && (*s <= '9')) { flags |= 1; Index: djgpp/src/libc/c99/math/makefile =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/c99/math/makefile,v retrieving revision 1.1 diff -p -u -r1.1 makefile --- djgpp/src/libc/c99/math/makefile 23 Jan 2003 19:50:51 -0000 1.1 +++ djgpp/src/libc/c99/math/makefile 26 Feb 2003 18:26:57 -0000 @@ -3,5 +3,6 @@ TOP=../.. SRC += hugevalf.c SRC += hugevall.c +SRC += nan.c include $(TOP)/../makefile.inc Index: djgpp/tests/libc/ansi/stdlib/strtod.c =================================================================== RCS file: /cvs/djgpp/djgpp/tests/libc/ansi/stdlib/strtod.c,v retrieving revision 1.1 diff -p -u -r1.1 strtod.c --- djgpp/tests/libc/ansi/stdlib/strtod.c 1 Jan 1998 21:45:46 -0000 1.1 +++ djgpp/tests/libc/ansi/stdlib/strtod.c 26 Feb 2003 18:27:05 -0000 @@ -9,6 +9,9 @@ static const char *testnum[] = { "1e6000000000", /* overflow */ "1e400", /* ditto */ "1e-400", /* underflow */ + "InF", /* infinity */ + "nAn", /* nan */ + "Nan()", /* nan */ 0 };