finalise NEWS.stable
[gnulib.git] / lib / strtod.c
index 060dffa..bf6955a 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-1992, 1997, 1999, 2003, 2006, 2008-2010 Free Software
+/* Copyright (C) 1991-1992, 1997, 1999, 2003, 2006, 2008-2011 Free Software
    Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
@@ -190,6 +190,21 @@ parse_number (const char *nptr,
 
 static double underlying_strtod (const char *, char **);
 
+/* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0.
+   ICC 10.0 has a bug when optimizing the expression -zero.
+   The expression -DBL_MIN * DBL_MIN does not work when cross-compiling
+   to PowerPC on MacOS X 10.5.  */
+#if defined __hpux || defined __sgi || defined __ICC
+static double
+compute_minus_zero (void)
+{
+  return -DBL_MIN * DBL_MIN;
+}
+# define minus_zero compute_minus_zero ()
+#else
+double minus_zero = -0.0;
+#endif
+
 /* Convert NPTR to a double.  If ENDPTR is not NULL, a pointer to the
    character after the last one used in the number is put in *ENDPTR.  */
 double
@@ -288,6 +303,7 @@ strtod (const char *nptr, char **endptr)
           && c_tolower (s[4]) == 'y')
         s += 5;
       num = HUGE_VAL;
+      errno = saved_errno;
     }
   else if (c_tolower (*s) == 'n'
            && c_tolower (s[1]) == 'a'
@@ -310,6 +326,7 @@ strtod (const char *nptr, char **endptr)
          to interpreting n-char-sequence as a hexadecimal number.  */
       if (s != end)
         num = NAN;
+      errno = saved_errno;
     }
   else
     {
@@ -320,6 +337,10 @@ strtod (const char *nptr, char **endptr)
 
   if (endptr != NULL)
     *endptr = (char *) s;
+  /* Special case -0.0, since at least ICC miscompiles negation.  We
+     can't use copysign(), as that drags in -lm on some platforms.  */
+  if (!num && negative)
+    return minus_zero;
   return negative ? -num : num;
 }