]> Savannah Git Hosting - gnulib.git/commitdiff
strtold: Revisit underflow behaviour.
authorBruno Haible <bruno@clisp.org>
Tue, 23 Jul 2024 10:40:58 +0000 (12:40 +0200)
committerBruno Haible <bruno@clisp.org>
Tue, 23 Jul 2024 10:41:05 +0000 (12:41 +0200)
* doc/posix-functions/strtold.texi: Mention broken mingw 5.0. Mention
that gradual underflow does not count as an error on MSVC.
* tests/test-strtold.h (test_function): Add a gradual underflow test.
Check the sign in case of flush-to-zero underflow.

ChangeLog
doc/posix-functions/strtold.texi
tests/test-strtold.h

index 3f086d2a9fe6c4af20c1ec6ed2ac65afc950d7f6..b4d5b8f9f8377991614ddece940b430417d4d24e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2024-07-23  Bruno Haible  <bruno@clisp.org>
 
+       strtold: Revisit underflow behaviour.
+       * doc/posix-functions/strtold.texi: Mention broken mingw 5.0. Mention
+       that gradual underflow does not count as an error on MSVC.
+       * tests/test-strtold.h (test_function): Add a gradual underflow test.
+       Check the sign in case of flush-to-zero underflow.
+
        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.
index cafcead911ea4f58faa61e544bf50791b539d102..3aada2c40547b8a93dda7ec081d3725642b803bd 100644 (file)
@@ -16,6 +16,10 @@ NetBSD 3.0, OpenBSD 3.8, Minix 3.1.8, Solaris 9, older Cygwin 1.7.x, MSVC 9, And
 This function returns a struct, not a @code{long double}, on some platforms:
 HP-UX 11.31/hppa.
 
+@item
+This function always returns a wrong value on some platforms:
+mingw 5.0.
+
 @item
 This function allows whitespace between @samp{e} and the exponent on
 some platforms:
@@ -50,6 +54,9 @@ and the exponent on some platforms:
 HP-UX 11.31/ia64.
 
 @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 underflow on some platforms:
 @c https://cygwin.com/ml/cygwin/2019-12/msg00072.html
 Cygwin 2.9.
@@ -61,6 +68,11 @@ and allocates an unbounded amount of stack on mingw 9.0.
 
 Portability problems not fixed by Gnulib:
 @itemize
+@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 b5d79dc07b210888fa9c54b4b7710781d803c162..bd12988c4cdf75c4b23eed72b04bc9397ec995d3 100644 (file)
@@ -481,7 +481,7 @@ test_function (long double (*my_strtold) (const char *, char **))
     ASSERT (errno == 0);
   }
 
-  /* Overflow/underflow.  */
+  /* Overflow.  */
   {
     const char input[] = "1E1000000";
     char *ptr;
@@ -502,6 +502,42 @@ test_function (long double (*my_strtold) (const char *, char **))
     ASSERT (ptr == input + 10);
     ASSERT (errno == ERANGE);
   }
+
+  /* Gradual underflow, resulting in a denormalized number.  */
+  {
+#if LDBL_MAX_EXP > 10000
+    const char input[] = "1e-4950";
+#else
+    const char input[] = "1e-320";
+#endif
+    char *ptr;
+    long double result;
+    errno = 0;
+    result = my_strtold (input, &ptr);
+    ASSERT (0.0L < result && result <= LDBL_MIN);
+    ASSERT (ptr == input + strlen (input));
+#if !defined _MSC_VER
+    ASSERT (errno == ERANGE);
+#endif
+  }
+  {
+#if LDBL_MAX_EXP > 10000
+    const char input[] = "-1e-4950";
+#else
+    const char input[] = "-1e-320";
+#endif
+    char *ptr;
+    long double result;
+    errno = 0;
+    result = my_strtold (input, &ptr);
+    ASSERT (-LDBL_MIN <= result && result < 0.0L);
+    ASSERT (ptr == input + strlen (input));
+#if !defined _MSC_VER
+    ASSERT (errno == ERANGE);
+#endif
+  }
+
+  /* Flush-to-zero underflow.  */
   {
     const char input[] = "1E-100000";
     char *ptr;
@@ -520,16 +556,14 @@ test_function (long double (*my_strtold) (const char *, char **))
     errno = 0;
     result = my_strtold (input, &ptr);
     ASSERT (-LDBL_MIN <= result && result <= 0.0L);
-#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.0L.
+       See also <https://sourceware.org/bugzilla/show_bug.cgi?id=5995>.  */
     ASSERT (!!signbit (result) == !!signbit (minus_zerol)); /* glibc-2.3.2, Haiku */
-#endif
     ASSERT (ptr == input + 10);
     ASSERT (errno == ERANGE);
   }
+
+  /* Space before the exponent.  */
   {
     const char input[] = "1E 1000000";
     char *ptr;