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

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

index f1e93da002b1f8d59c835a4c7297187f9be32c46..3da7b0104983054b2f337f19956b8ba796966bbf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2024-07-23  Bruno Haible  <bruno@clisp.org>
+
+       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.
+       Mention that gradual underflow does not count as an error on Cygwin 2.9,
+       mingw, MSVC.
+       * m4/strtof.m4 (gl_FUNC_STRTOF): Test against the mingw overflow bug.
+       * tests/test-strtof.h (test_function): Add a gradual underflow test.
+       Check the sign in case of flush-to-zero underflow.
+
 2024-07-23  Bruno Haible  <bruno@clisp.org>
 
        strtof, strtod, strtold: Fix underflow behaviour of system function.
index b7bf64e9343512e8f2af76d0dde8ec1e1d8ac674..cffe033cf0d1f15903350f60a9c94717d5f24941 100644 (file)
@@ -19,7 +19,22 @@ glibc 2.4, Mac OS X 10.5, FreeBSD 6.2.
 
 @item
 This function fails to parse @samp{NaN()} on some platforms:
-glibc-2.5, FreeBSD 6.2.
+glibc 2.5, FreeBSD 6.2.
+
+@item
+This function misparses @samp{nan(} on some platforms:
+macOS 10.6.6.
+
+@item
+This function fails to set @code{errno} upon overflow on some platforms:
+mingw 5.0.
+
+@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:
+Cygwin 2.9, mingw 5.0.
 @end itemize
 
 Portability problems not fixed by Gnulib:
@@ -39,6 +54,11 @@ This function fails to correctly parse very long strings on some
 platforms:
 Mac OS X 10.5, FreeBSD 6.2, NetBSD 5.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 e37310ebded3d1541db78124913ef46879cccfb4..71516f1bf69105cf53faddd706cbf52436607491 100644 (file)
@@ -1,5 +1,5 @@
 # strtof.m4
-# serial 3
+# serial 4
 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,
@@ -83,6 +83,17 @@ numeric_equal (float x, float y)
     if (value != HUGE_VAL || term != (string + 3) || errno)
       result |= 8;
   }
+  {
+    /* In mingw 5.0 without __USE_MINGW_ANSI_STDIO and __USE_MINGW_STRTOX,
+       strtof does not set errno upon overflow.  */
+    const char *string = "1e50";
+    char *term;
+    float value;
+    errno = 0;
+    value = strtof (string, &term);
+    if (value != HUGE_VAL || term != (string + 4) || errno != ERANGE)
+      result |= 8;
+  }
   {
     /* glibc 2.7 and cygwin 1.5.24 misparse "nan()".  */
     const char *string = "nan()";
@@ -92,7 +103,7 @@ numeric_equal (float x, float 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;
     float value = strtof (string, &term);
index 1a7588f608e0fbc63834174b5a43e85e8c692cdf..2ac6b898dab1b5867be543df7de74887db3e2b64 100644 (file)
@@ -481,7 +481,7 @@ test_function (float (*my_strtof) (const char *, char **))
     ASSERT (errno == 0);
   }
 
-  /* Overflow/underflow.  */
+  /* Overflow.  */
   {
     const char input[] = "1E1000000";
     char *ptr;
@@ -502,6 +502,34 @@ test_function (float (*my_strtof) (const char *, char **))
     ASSERT (ptr == input + 10);
     ASSERT (errno == ERANGE);
   }
+
+  /* Gradual underflow, resulting in a denormalized number.  */
+  {
+    const char input[] = "1e-40";
+    char *ptr;
+    float result;
+    errno = 0;
+    result = my_strtof (input, &ptr);
+    ASSERT (0.0f < result && result <= FLT_MIN);
+    ASSERT (ptr == input + 5);
+#if !defined _MSC_VER
+    ASSERT (errno == ERANGE);
+#endif
+  }
+  {
+    const char input[] = "-1e-40";
+    char *ptr;
+    float result;
+    errno = 0;
+    result = my_strtof (input, &ptr);
+    ASSERT (-FLT_MIN <= result && result < 0.0f);
+    ASSERT (ptr == input + 6);
+#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 (float (*my_strtof) (const char *, char **))
     errno = 0;
     result = my_strtof (input, &ptr);
     ASSERT (-FLT_MIN <= result && result <= 0.0f);
-#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.0f.
+       See also <https://sourceware.org/bugzilla/show_bug.cgi?id=5995>.  */
     ASSERT (!!signbit (result) == !!signbit (minus_zerof)); /* glibc-2.3.6, mingw */
-#endif
     ASSERT (ptr == input + 10);
     ASSERT (errno == ERANGE);
   }
+
+  /* Space before the exponent.  */
   {
     const char input[] = "1E 1000000";
     char *ptr;