about summary refs log tree commit diff
path: root/stdlib
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib')
-rw-r--r--stdlib/strtod.c25
-rw-r--r--stdlib/strtof.c6
-rw-r--r--stdlib/strtold.c7
3 files changed, 37 insertions, 1 deletions
diff --git a/stdlib/strtod.c b/stdlib/strtod.c
index cff75bd4ad..760ecd26a7 100644
--- a/stdlib/strtod.c
+++ b/stdlib/strtod.c
@@ -31,6 +31,12 @@
 # endif
 # define MPN2FLOAT	__mpn_construct_double
 # define FLOAT_HUGE_VAL	HUGE_VAL
+# define SET_MANTISSA(flt, mant) \
+  do { union ieee754_double u;						      \
+       u.d = (flt);							      \
+       u.ieee.mantissa0 = ((mant) >> 32) & 0xfffff;			      \
+       u.ieee.mantissa1 = (mant) & 0xffffffff;				      \
+  } while (0)
 #endif
 
 #ifdef USE_WIDE_CHAR
@@ -44,6 +50,7 @@
 # define ISXDIGIT(Ch) iswxdigit (Ch)
 # define TOLOWER(Ch) towlower (Ch)
 # define STRNCASECMP(S1, S2, N) __wcsncasecmp ((S1), (S2), (N))
+# define STRTOULL(S, E, B) wcstoull ((S), (E), (B))
 #else
 # define STRING_TYPE char
 # define CHAR_TYPE char
@@ -53,6 +60,7 @@
 # define ISXDIGIT(Ch) isxdigit (Ch)
 # define TOLOWER(Ch) tolower (Ch)
 # define STRNCASECMP(S1, S2, N) __strncasecmp ((S1), (S2), (N))
+# define STRTOULL(S, E, B) strtoull ((S), (E), (B))
 #endif
 /* End of configuration part.  */
 
@@ -461,6 +469,8 @@ INTERNAL (STRTOF) (nptr, endptr, group)
 
       if (TOLOWER (c) == L_('n') && STRNCASECMP (cp, L_("an"), 2) == 0)
 	{
+	  FLOAT retval = NAN;
+
 	  /* Return NaN.  */
 	  if (endptr != NULL)
 	    {
@@ -480,12 +490,25 @@ INTERNAL (STRTOF) (nptr, endptr, group)
 		    /* The closing brace is missing.  Only match the NAN
 		       part.  */
 		    cp = startp;
+		  else
+		    {
+		      /* This is a system-dependent way to specify the
+			 bitmask used for the NaN.  We expect it to be
+			 a number which is put in the mantissa of the
+			 number.  */
+		      STRING_TYPE *endp;
+		      unsigned long long int mant;
+
+		      mant = STRTOULL (startp, &endp, 0);
+		      if (endp == cp)
+			SET_MANTISSA (retval, mant);
+		    }
 		}
 
 	      *endptr = (STRING_TYPE *) cp;
 	    }
 
-	  return NAN;
+	  return retval;
 	}
 
       /* It is really a text we do not recognize.  */
diff --git a/stdlib/strtof.c b/stdlib/strtof.c
index 8692a3ac8f..0a0046daf9 100644
--- a/stdlib/strtof.c
+++ b/stdlib/strtof.c
@@ -6,5 +6,11 @@
 #define	STRTOF		strtof
 #define	MPN2FLOAT	__mpn_construct_float
 #define	FLOAT_HUGE_VAL	HUGE_VALF
+#define SET_MANTISSA(flt, mant) \
+  do { union ieee754_float u;						      \
+       u.f = (flt);							      \
+       u.ieee.mantissa = (mant) & 0x7fffff;				      \
+       (flt) = u.f;							      \
+  } while (0)
 
 #include "strtod.c"
diff --git a/stdlib/strtold.c b/stdlib/strtold.c
index 9d80543377..1dc0ac37c2 100644
--- a/stdlib/strtold.c
+++ b/stdlib/strtold.c
@@ -6,5 +6,12 @@
 #define	STRTOF		strtold
 #define	MPN2FLOAT	__mpn_construct_long_double
 #define	FLOAT_HUGE_VAL	HUGE_VALL
+#define SET_MANTISSA(flt, mant) \
+  do { union ieee854_long_double u;					      \
+       u.d = (flt);							      \
+       u.ieee.mantissa0 = ((mant) >> 32) & 0x7fffffff;			      \
+       u.ieee.mantissa1 = (mant) & 0xffffffff;				      \
+       (flt) = u.d;							      \
+  } while (0)
 
 #include "strtod.c"