delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2003/02/26/13:38:55

From: <ams AT ludd DOT luth DOT se>
Message-Id: <200302261837.h1QIbPN04902@speedy.ludd.luth.se>
Subject: strtod.c: inf and nan support
To: DJGPP-WORKERS <djgpp-workers AT delorie DOT com>
Date: Wed, 26 Feb 2003 19:37:25 +0100 (CET)
X-Mailer: ELM [version 2.4ME+ PL78 (25)]
MIME-Version: 1.0
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 <libc/ieee.h>

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 <float.h>
 #include <errno.h>
 #include <ctype.h>
+#include <string.h>
 #include <libc/unconst.h>
 
 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(<whatever>). */
+  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
 };
 

- Raw text -


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