]> Savannah Git Hosting - gnulib.git/commitdiff
strtod: Revisit underflow behaviour.
authorBruno Haible <bruno@clisp.org>
Tue, 23 Jul 2024 10:40:37 +0000 (12:40 +0200)
committerBruno Haible <bruno@clisp.org>
Tue, 23 Jul 2024 10:40:49 +0000 (12:40 +0200)
* doc/posix-functions/strtod.texi: Mention the macOS bug. Mention that
gradual underflow does not count as an error on Cygwin 2.9 and MSVC.
* m4/strtod.m4 (gl_FUNC_STRTOD): Update comment.
* tests/test-strtod.h (test_function): Add a gradual underflow test.
Check the sign in case of flush-to-zero underflow.

ChangeLog
doc/posix-functions/strtod.texi
m4/strtod.m4
tests/test-strtod.h

index 3da7b0104983054b2f337f19956b8ba796966bbf..3f086d2a9fe6c4af20c1ec6ed2ac65afc950d7f6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2024-07-23  Bruno Haible  <bruno@clisp.org>
 
+       strtod: Revisit underflow behaviour.
+       * doc/posix-functions/strtod.texi: Mention the macOS bug. Mention that
+       gradual underflow does not count as an error on Cygwin 2.9 and MSVC.
+       * m4/strtod.m4 (gl_FUNC_STRTOD): Update comment.
+       * tests/test-strtod.h (test_function): Add a gradual underflow test.
+       Check the sign in case of flush-to-zero underflow.
+
        strtof: Revisit underflow behaviour.
        * doc/posix-functions/strtof.texi: Mention the macOS bug. Mention the
        mingw overflow bug. Mention the underflow bugs on Cygwin 2.9 and mingw.
index 9b470eb465652aea83004b6e9588436c76ac65f2..a7d0143a13db410f2a4a1328a2175e65ed6a8ec2 100644 (file)
@@ -31,7 +31,7 @@ OpenBSD 4.0, HP-UX 11.11, Solaris 9, mingw, MSVC 14.
 
 @item
 This function fails to parse @samp{NaN()} on some platforms:
-glibc-2.3.6, Mac OS X 10.5, FreeBSD 6.2, OpenBSD 4.0, AIX 7.1, HP-UX 11.11, Cygwin < 1.5.25-11, mingw, MSVC 14.
+glibc 2.3.6, Mac OS X 10.5, FreeBSD 6.2, OpenBSD 4.0, AIX 7.1, HP-UX 11.11, Cygwin < 1.5.25-11, mingw, MSVC 14.
 
 @item
 This function fails to parse @samp{NaN(@var{n-char-sequence})} on some
@@ -41,7 +41,11 @@ OpenBSD 4.0, HP-UX 11.11, mingw, MSVC 14.
 @item
 This function parses @samp{NaN(@var{n-char-sequence})}, but returns
 the wrong end pointer on some platforms:
-glibc-2.4, AIX 7.1.
+glibc 2.4, AIX 7.1.
+
+@item
+This function misparses @samp{nan(} on some platforms:
+macOS 10.6.6.
 
 @item
 This function fails to parse C99 hexadecimal floating point on some
@@ -57,6 +61,14 @@ HP-UX 11.31/ia64.
 This function returns the wrong end pointer for @samp{0x1p} on some
 platforms:
 AIX 7.1.
+
+@item
+@c The term "underflow", as defined by ISO C23 ยง 7.12.1.(6), includes both
+@c "gradual underflow" (result is a denormalized number) and "flush-to-zero
+@c underflow" (result is zero).
+This function fails to set @code{errno} upon gradual underflow (resulting
+in a denormalized number) on some platforms:
+Cygwin 2.9.
 @end itemize
 
 Portability problems fixed by Gnulib module @code{strtod-obsolete}:
@@ -82,6 +94,11 @@ This function fails to correctly parse very long strings on some
 platforms:
 Mac OS X 10.5, FreeBSD 6.2, NetBSD 5.0, OpenBSD 4.0, Cygwin, mingw, MSVC 14.
 
+@item
+This function fails to set @code{errno} upon gradual underflow (resulting
+in a denormalized number) on some platforms:
+MSVC 14.
+
 @item
 The replacement function does not always return correctly rounded results.
 @end itemize
index 2ccbf3139a49fb26968bd40cff9824b65855b329..e974478845df118b4d12f386d32e9704064e2fc2 100644 (file)
@@ -1,5 +1,5 @@
 # strtod.m4
-# serial 30
+# serial 31
 dnl Copyright (C) 2002-2003, 2006-2024 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -92,7 +92,7 @@ numeric_equal (double x, double y)
       result |= 16;
   }
   {
-    /* darwin 10.6.1 misparses "nan(".  */
+    /* Darwin 10.6.1 (macOS 10.6.6) misparses "nan(".  */
     const char *string = "nan(";
     char *term;
     double value = strtod (string, &term);
index 48d784f36842d6ede360c09335c547c6031ddf75..c806953e844ea8a97d7a9d68454700c4511dabdf 100644 (file)
@@ -481,7 +481,7 @@ test_function (double (*my_strtod) (const char *, char **))
     ASSERT (errno == 0);
   }
 
-  /* Overflow/underflow.  */
+  /* Overflow.  */
   {
     const char input[] = "1E1000000";
     char *ptr;
@@ -502,6 +502,34 @@ test_function (double (*my_strtod) (const char *, char **))
     ASSERT (ptr == input + 10);
     ASSERT (errno == ERANGE);
   }
+
+  /* Gradual underflow, resulting in a denormalized number.  */
+  {
+    const char input[] = "1e-320";
+    char *ptr;
+    double result;
+    errno = 0;
+    result = my_strtod (input, &ptr);
+    ASSERT (0.0 < result && result <= DBL_MIN);
+    ASSERT (ptr == input + 6);
+#if !defined _MSC_VER
+    ASSERT (errno == ERANGE);
+#endif
+  }
+  {
+    const char input[] = "-1e-320";
+    char *ptr;
+    double result;
+    errno = 0;
+    result = my_strtod (input, &ptr);
+    ASSERT (-DBL_MIN <= result && result < 0.0);
+    ASSERT (ptr == input + 7);
+#if !defined _MSC_VER
+    ASSERT (errno == ERANGE);
+#endif
+  }
+
+  /* Flush-to-zero underflow.  */
   {
     const char input[] = "1E-100000";
     char *ptr;
@@ -520,16 +548,14 @@ test_function (double (*my_strtod) (const char *, char **))
     errno = 0;
     result = my_strtod (input, &ptr);
     ASSERT (-DBL_MIN <= result && result <= 0.0);
-#if 0
-    /* FIXME - this is glibc bug 5995; POSIX allows returning positive
-       0 on negative underflow, even though quality of implementation
-       demands preserving the sign.  Disable this test until fixed
-       glibc is more prevalent.  */
+    /* Negative underflow.  Expect a negative sign, although POSIX allows +0.0.
+       See also <https://sourceware.org/bugzilla/show_bug.cgi?id=5995>.  */
     ASSERT (!!signbit (result) == !!signbit (minus_zerod)); /* glibc-2.3.6, mingw */
-#endif
     ASSERT (ptr == input + 10);
     ASSERT (errno == ERANGE);
   }
+
+  /* Space before the exponent.  */
   {
     const char input[] = "1E 1000000";
     char *ptr;