From: Bruno Haible <bruno@clisp.org>
To: bug-gnulib@gnu.org
Subject: new modules getpayload, getpayloadf, getpayloadl
Date: Wed, 17 Apr 2024 15:56:32 +0200 [thread overview]
Message-ID: <13436243.RAW8MR3E7N@nimes> (raw)
[-- Attachment #1: Type: text/plain, Size: 2225 bytes --]
ISO C 23 specifies in the (optional, but normative) Annex F also functions
for extracting the payload of a quiet or signalling NaN. This patch series
implements them.
2024-04-17 Bruno Haible <bruno@clisp.org>
getpayloadl: Add tests.
* tests/test-getpayloadl.c: New file.
* modules/getpayloadl-tests: New file.
getpayloadl: New module.
* lib/math.in.h (getpayloadl): New declaration.
* lib/getpayloadl.c: New file.
* m4/math_h.m4 (gl_MATH_H): Test whether getpayloadl is declared.
(gl_MATH_H_REQUIRE_DEFAULTS): Initialize GNULIB_GETPAYLOADL.
(gl_MATH_H_DEFAULTS): Initialize HAVE_GETPAYLOADL, REPLACE_GETPAYLOADL.
* modules/math (Makefile.am): Substitute GNULIB_GETPAYLOADL,
HAVE_GETPAYLOADL, REPLACE_GETPAYLOADL.
* modules/getpayloadl: New file.
* doc/posix-functions/getpayloadl.texi: Mention the new module and the
glibc bug.
2024-04-17 Bruno Haible <bruno@clisp.org>
getpayloadf: Add tests.
* tests/test-getpayloadf.c: New file.
* modules/getpayloadf-tests: New file.
getpayloadf: New module.
* lib/math.in.h (getpayloadf): New declaration.
* lib/getpayloadf.c: New file.
* m4/math_h.m4 (gl_MATH_H): Test whether getpayloadf is declared.
(gl_MATH_H_REQUIRE_DEFAULTS): Initialize GNULIB_GETPAYLOADF.
(gl_MATH_H_DEFAULTS): Initialize HAVE_GETPAYLOADF, REPLACE_GETPAYLOADF.
* modules/math (Makefile.am): Substitute GNULIB_GETPAYLOADF,
HAVE_GETPAYLOADF, REPLACE_GETPAYLOADF.
* modules/getpayloadf: New file.
* doc/posix-functions/getpayloadf.texi: Mention the new module and the
glibc bug.
2024-04-17 Bruno Haible <bruno@clisp.org>
getpayload: Add tests.
* tests/test-getpayload.c: New file.
* modules/getpayload-tests: New file.
getpayload: New module.
* lib/math.in.h (getpayload): New declaration.
* lib/getpayload.c: New file.
* m4/getpayload.m4: New file.
* m4/math_h.m4 (gl_MATH_H): Test whether getpayload is declared.
(gl_MATH_H_REQUIRE_DEFAULTS): Initialize GNULIB_GETPAYLOAD.
(gl_MATH_H_DEFAULTS): Initialize HAVE_GETPAYLOAD, REPLACE_GETPAYLOAD.
* modules/math (Makefile.am): Substitute GNULIB_GETPAYLOAD,
HAVE_GETPAYLOAD, REPLACE_GETPAYLOAD.
* modules/getpayload: New file.
* doc/posix-functions/getpayload.texi: Mention the new module and the
glibc bug.
[-- Attachment #2: 0001-getpayload-New-module.patch --]
[-- Type: text/x-patch, Size: 17003 bytes --]
From 20b8f23dca46e1383eb5e9f922c1ca93a3fac425 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Wed, 17 Apr 2024 10:57:05 +0200
Subject: [PATCH 1/6] getpayload: New module.
* lib/math.in.h (getpayload): New declaration.
* lib/getpayload.c: New file.
* m4/getpayload.m4: New file.
* m4/math_h.m4 (gl_MATH_H): Test whether getpayload is declared.
(gl_MATH_H_REQUIRE_DEFAULTS): Initialize GNULIB_GETPAYLOAD.
(gl_MATH_H_DEFAULTS): Initialize HAVE_GETPAYLOAD, REPLACE_GETPAYLOAD.
* modules/math (Makefile.am): Substitute GNULIB_GETPAYLOAD,
HAVE_GETPAYLOAD, REPLACE_GETPAYLOAD.
* modules/getpayload: New file.
* doc/posix-functions/getpayload.texi: Mention the new module and the
glibc bug.
---
ChangeLog | 15 +++
doc/posix-functions/getpayload.texi | 12 +-
lib/getpayload.c | 54 ++++++++
lib/math.in.h | 24 ++++
m4/getpayload.m4 | 183 ++++++++++++++++++++++++++++
m4/math_h.m4 | 9 +-
modules/getpayload | 37 ++++++
modules/math | 3 +
8 files changed, 331 insertions(+), 6 deletions(-)
create mode 100644 lib/getpayload.c
create mode 100644 m4/getpayload.m4
create mode 100644 modules/getpayload
diff --git a/ChangeLog b/ChangeLog
index ffe35d5d1d..6fbcff9835 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2024-04-17 Bruno Haible <bruno@clisp.org>
+
+ getpayload: New module.
+ * lib/math.in.h (getpayload): New declaration.
+ * lib/getpayload.c: New file.
+ * m4/getpayload.m4: New file.
+ * m4/math_h.m4 (gl_MATH_H): Test whether getpayload is declared.
+ (gl_MATH_H_REQUIRE_DEFAULTS): Initialize GNULIB_GETPAYLOAD.
+ (gl_MATH_H_DEFAULTS): Initialize HAVE_GETPAYLOAD, REPLACE_GETPAYLOAD.
+ * modules/math (Makefile.am): Substitute GNULIB_GETPAYLOAD,
+ HAVE_GETPAYLOAD, REPLACE_GETPAYLOAD.
+ * modules/getpayload: New file.
+ * doc/posix-functions/getpayload.texi: Mention the new module and the
+ glibc bug.
+
2024-04-16 Sam James <sam@gentoo.org>
wchar: Fix serial number.
diff --git a/doc/posix-functions/getpayload.texi b/doc/posix-functions/getpayload.texi
index da6154e61f..d5ea38d70c 100644
--- a/doc/posix-functions/getpayload.texi
+++ b/doc/posix-functions/getpayload.texi
@@ -10,15 +10,19 @@
@url{https://www.gnu.org/software/libc/manual/html_node/FP-Bit-Twiddling.html}.
@end ifnotinfo
-Gnulib module: ---
+Gnulib module: getpayload
Portability problems fixed by Gnulib:
@itemize
+@item
+This function is missing on all non-glibc platforms:
+glibc 2.24, macOS 11.1, FreeBSD 14.0, NetBSD 10.0, OpenBSD 6.7, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, Solaris 11.4, Cygwin 2.9, mingw, MSVC 14, Android 9.0.
+@item
+This function returns a wrong result for non-NaN arguments on some platforms:
+@c https://sourceware.org/bugzilla/show_bug.cgi?id=26073
+glibc 2.31.
@end itemize
Portability problems not fixed by Gnulib:
@itemize
-@item
-This function is missing on all non-glibc platforms:
-glibc 2.24, macOS 11.1, FreeBSD 14.0, NetBSD 10.0, OpenBSD 6.7, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, Solaris 11.4, Cygwin 2.9, mingw, MSVC 14, Android 9.0.
@end itemize
diff --git a/lib/getpayload.c b/lib/getpayload.c
new file mode 100644
index 0000000000..43979d595f
--- /dev/null
+++ b/lib/getpayload.c
@@ -0,0 +1,54 @@
+/* Extract the payload of a NaN 'double'.
+ Copyright 2024 Free Software Foundation, Inc.
+
+ This file is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible. */
+
+#include <config.h>
+
+/* Specification. */
+#include <math.h>
+
+#include <float.h>
+#include <stdint.h>
+#include <string.h>
+
+double
+getpayload (const double *value)
+{
+ if (isnand (*value))
+ {
+#if DBL_MANT_DIG == 53
+ union { uint64_t i; double f; } x;
+# if 0
+ x.f = *value;
+# else
+ /* On 32-bit x86 processors, as well as on x86_64 processors with
+ CC="gcc -mfpmath=387", the evaluation of *value above is done
+ through an 'fldl' instruction, which converts a signalling NaN to
+ a quiet NaN. See
+ <https://lists.gnu.org/archive/html/bug-gnulib/2023-10/msg00060.html>
+ for details. Use memcpy to avoid this. */
+ memcpy (&x.f, value, sizeof (double));
+# endif
+ int64_t payload = x.i & (((uint64_t) 1 << (DBL_MANT_DIG - 2)) - 1);
+ return payload;
+#else
+# error "Please port gnulib getpayload.c to your platform!"
+#endif
+ }
+ else
+ return -1.0;
+}
diff --git a/lib/math.in.h b/lib/math.in.h
index 7bb7976b61..2e7dde2e07 100644
--- a/lib/math.in.h
+++ b/lib/math.in.h
@@ -2774,6 +2774,30 @@ _GL_WARN_REAL_FLOATING_DECL (signbit);
#endif
+#if @GNULIB_GETPAYLOAD@
+# if @REPLACE_GETPAYLOAD@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef getpayload
+# define getpayload rpl_getpayload
+# endif
+_GL_FUNCDECL_RPL (getpayload, double, (const double *));
+_GL_CXXALIAS_RPL (getpayload, double, (const double *));
+# else
+# if !@HAVE_GETPAYLOAD@
+_GL_FUNCDECL_SYS (getpayload, double, (const double *));
+# endif
+_GL_CXXALIAS_SYS (getpayload, double, (const double *));
+# endif
+_GL_CXXALIASWARN (getpayload);
+#elif defined GNULIB_POSIXCHECK
+# undef getpayload
+# if HAVE_RAW_DECL_GETPAYLOAD
+_GL_WARN_ON_USE (getpayload, "getpayload is unportable - "
+ "use gnulib module getpayload for portability");
+# endif
+#endif
+
+
#if @GNULIB_SETPAYLOADF@
# if !@HAVE_SETPAYLOADF@
_GL_FUNCDECL_SYS (setpayloadf, int, (float *, float));
diff --git a/m4/getpayload.m4 b/m4/getpayload.m4
new file mode 100644
index 0000000000..c41f0c25d8
--- /dev/null
+++ b/m4/getpayload.m4
@@ -0,0 +1,183 @@
+# getpayload.m4
+# serial 1
+dnl Copyright 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,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_GETPAYLOADF],
+[
+ AC_REQUIRE([gl_MATH_H_DEFAULTS])
+ AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+
+ gl_MATHFUNC([getpayloadf], [float], [(float const *)])
+ if test $gl_cv_func_getpayloadf_no_libm != yes \
+ && test $gl_cv_func_getpayloadf_in_libm != yes; then
+ HAVE_GETPAYLOADF=0
+ else
+ dnl glibc versions < 2.32 return a wrong value,
+ dnl see <https://sourceware.org/bugzilla/show_bug.cgi?id=26073>.
+ AC_CACHE_CHECK([whether getpayloadf works],
+ [gl_cv_func_getpayloadf_works],
+ [AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <math.h>
+ ]],
+ [[float x = 2.718281828459045f;
+ return getpayloadf (&x) != -1.0f;
+ ]])
+ ],
+ [gl_cv_func_getpayloadf_works=yes],
+ [gl_cv_func_getpayloadf_works=no],
+ [case "$host_os" in
+ # Guess no on glibc versions < 2.32.
+ *-gnu* | gnu*)
+ AC_EGREP_CPP([Unlucky],
+ [
+#include <features.h>
+#ifdef __GNU_LIBRARY__
+ #if (__GLIBC__ == 2 && __GLIBC_MINOR__ < 32)
+ Unlucky GNU user
+ #endif
+#endif
+ ],
+ [gl_cv_func_getpayloadf_works="guessing no"],
+ [gl_cv_func_getpayloadf_works="guessing yes"])
+ ;;
+ # Guess yes otherwise.
+ *) gl_cv_func_getpayloadf_works="guessing yes" ;;
+ esac
+ ])
+ ])
+ case "$gl_cv_func_getpayloadf_works" in
+ *yes) ;;
+ *) REPLACE_GETPAYLOADF=1 ;;
+ esac
+ fi
+ if test $HAVE_GETPAYLOADF = 0 || test $REPLACE_GETPAYLOADF = 1; then
+ GETPAYLOADF_LIBM='$(ISNANF_LIBM)'
+ fi
+ AC_SUBST([GETPAYLOADF_LIBM])
+])
+
+AC_DEFUN_ONCE([gl_FUNC_GETPAYLOAD],
+[
+ AC_REQUIRE([gl_MATH_H_DEFAULTS])
+ AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+
+ gl_MATHFUNC([getpayload], [double], [(double const *)])
+ if test $gl_cv_func_getpayload_no_libm != yes \
+ && test $gl_cv_func_getpayload_in_libm != yes; then
+ HAVE_GETPAYLOAD=0
+ else
+ dnl glibc versions < 2.32 return a wrong value,
+ dnl see <https://sourceware.org/bugzilla/show_bug.cgi?id=26073>.
+ AC_CACHE_CHECK([whether getpayload works],
+ [gl_cv_func_getpayload_works],
+ [AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <math.h>
+ ]],
+ [[double x = 2.718281828459045;
+ return getpayload (&x) != -1.0;
+ ]])
+ ],
+ [gl_cv_func_getpayload_works=yes],
+ [gl_cv_func_getpayload_works=no],
+ [case "$host_os" in
+ # Guess no on glibc versions < 2.32.
+ *-gnu* | gnu*)
+ AC_EGREP_CPP([Unlucky],
+ [
+#include <features.h>
+#ifdef __GNU_LIBRARY__
+ #if (__GLIBC__ == 2 && __GLIBC_MINOR__ < 32)
+ Unlucky GNU user
+ #endif
+#endif
+ ],
+ [gl_cv_func_getpayload_works="guessing no"],
+ [gl_cv_func_getpayload_works="guessing yes"])
+ ;;
+ # Guess yes otherwise.
+ *) gl_cv_func_getpayload_works="guessing yes" ;;
+ esac
+ ])
+ ])
+ case "$gl_cv_func_getpayload_works" in
+ *yes) ;;
+ *) REPLACE_GETPAYLOAD=1 ;;
+ esac
+ fi
+ if test $HAVE_GETPAYLOAD = 0 || test $REPLACE_GETPAYLOAD = 1; then
+ GETPAYLOAD_LIBM='$(ISNAND_LIBM)'
+ fi
+ AC_SUBST([GETPAYLOAD_LIBM])
+])
+
+AC_DEFUN([gl_FUNC_GETPAYLOADL],
+[
+ AC_REQUIRE([gl_MATH_H_DEFAULTS])
+ AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ AC_REQUIRE([gl_LONG_DOUBLE_VS_DOUBLE])
+
+ gl_MATHFUNC([getpayloadl], [long double], [(long double const *)])
+ if test $gl_cv_func_getpayloadl_no_libm != yes \
+ && test $gl_cv_func_getpayloadl_in_libm != yes; then
+ HAVE_GETPAYLOADL=0
+ else
+ dnl glibc versions < 2.32 return a wrong value,
+ dnl see <https://sourceware.org/bugzilla/show_bug.cgi?id=26073>.
+ AC_CACHE_CHECK([whether getpayloadl works],
+ [gl_cv_func_getpayloadl_works],
+ [AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <math.h>
+ ]],
+ [[long double x = 2.718281828459045L;
+ return getpayloadl (&x) != -1.0L;
+ ]])
+ ],
+ [gl_cv_func_getpayloadl_works=yes],
+ [gl_cv_func_getpayloadl_works=no],
+ [case "$host_os" in
+ # Guess no on glibc versions < 2.32.
+ *-gnu* | gnu*)
+ AC_EGREP_CPP([Unlucky],
+ [
+#include <features.h>
+#ifdef __GNU_LIBRARY__
+ #if (__GLIBC__ == 2 && __GLIBC_MINOR__ < 32)
+ Unlucky GNU user
+ #endif
+#endif
+ ],
+ [gl_cv_func_getpayloadl_works="guessing no"],
+ [gl_cv_func_getpayloadl_works="guessing yes"])
+ ;;
+ # Guess yes otherwise.
+ *) gl_cv_func_getpayloadl_works="guessing yes" ;;
+ esac
+ ])
+ ])
+ case "$gl_cv_func_getpayloadl_works" in
+ *yes) ;;
+ *) REPLACE_GETPAYLOADL=1 ;;
+ esac
+ fi
+ if test $HAVE_GETPAYLOADL = 0 || test $REPLACE_GETPAYLOADL = 1; then
+ dnl Find libraries needed to link lib/getpayloadl.c.
+ if test $HAVE_SAME_LONG_DOUBLE_AS_DOUBLE = 1; then
+ AC_REQUIRE([gl_FUNC_GETPAYLOAD])
+ GETPAYLOADL_LIBM="$GETPAYLOAD_LIBM"
+ else
+ GETPAYLOADL_LIBM='$(ISNANL_LIBM)'
+ fi
+ dnl Prerequisite of lib/getpayloadl.c.
+ gl_LONG_DOUBLE_EXPONENT_LOCATION
+ fi
+ AC_SUBST([GETPAYLOADL_LIBM])
+])
diff --git a/m4/math_h.m4 b/m4/math_h.m4
index 7bcacf6959..370ea14051 100644
--- a/m4/math_h.m4
+++ b/m4/math_h.m4
@@ -1,5 +1,5 @@
# math_h.m4
-# serial 132
+# serial 133
dnl Copyright (C) 2007-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,
@@ -43,7 +43,9 @@ AC_DEFUN_ONCE([gl_MATH_H]
cbrt cbrtf cbrtl ceilf ceill copysign copysignf copysignl cosf cosl coshf
expf expl exp2 exp2f exp2l expm1 expm1f expm1l
fabsf fabsl floorf floorl fma fmaf fmal
- fmod fmodf fmodl frexpf frexpl hypotf hypotl
+ fmod fmodf fmodl frexpf frexpl
+ getpayload
+ hypotf hypotl
ilogb ilogbf ilogbl
ldexpf ldexpl
log logf logl log10 log10f log10l log1p log1pf log1pl log2 log2f log2l
@@ -117,6 +119,7 @@ AC_DEFUN([gl_MATH_H_REQUIRE_DEFAULTS]
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FREXPF])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FREXP])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FREXPL])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETPAYLOAD])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_HYPOT])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_HYPOTF])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_HYPOTL])
@@ -223,6 +226,7 @@ AC_DEFUN([gl_MATH_H_DEFAULTS]
HAVE_FMODF=1; AC_SUBST([HAVE_FMODF])
HAVE_FMODL=1; AC_SUBST([HAVE_FMODL])
HAVE_FREXPF=1; AC_SUBST([HAVE_FREXPF])
+ HAVE_GETPAYLOAD=1; AC_SUBST([HAVE_GETPAYLOAD])
HAVE_HYPOTF=1; AC_SUBST([HAVE_HYPOTF])
HAVE_HYPOTL=1; AC_SUBST([HAVE_HYPOTL])
HAVE_ILOGB=1; AC_SUBST([HAVE_ILOGB])
@@ -332,6 +336,7 @@ AC_DEFUN([gl_MATH_H_DEFAULTS]
REPLACE_FREXPF=0; AC_SUBST([REPLACE_FREXPF])
REPLACE_FREXP=0; AC_SUBST([REPLACE_FREXP])
REPLACE_FREXPL=0; AC_SUBST([REPLACE_FREXPL])
+ REPLACE_GETPAYLOAD=0; AC_SUBST([REPLACE_GETPAYLOAD])
REPLACE_HUGE_VAL=0; AC_SUBST([REPLACE_HUGE_VAL])
REPLACE_HYPOT=0; AC_SUBST([REPLACE_HYPOT])
REPLACE_HYPOTF=0; AC_SUBST([REPLACE_HYPOTF])
diff --git a/modules/getpayload b/modules/getpayload
new file mode 100644
index 0000000000..5721cb82a9
--- /dev/null
+++ b/modules/getpayload
@@ -0,0 +1,37 @@
+Description:
+getpayload function: extract the payload of a NaN
+
+Files:
+lib/getpayload.c
+m4/mathfunc.m4
+m4/getpayload.m4
+
+Depends-on:
+math
+extensions
+float [test $HAVE_GETPAYLOAD = 0 || test $REPLACE_GETPAYLOAD = 1]
+stdint [test $HAVE_GETPAYLOAD = 0 || test $REPLACE_GETPAYLOAD = 1]
+isnand [test $HAVE_GETPAYLOAD = 0 || test $REPLACE_GETPAYLOAD = 1]
+
+configure.ac:
+gl_FUNC_GETPAYLOAD
+gl_CONDITIONAL([GL_COND_OBJ_GETPAYLOAD],
+ [test $HAVE_GETPAYLOAD = 0 || test $REPLACE_GETPAYLOAD = 1])
+gl_MATH_MODULE_INDICATOR([getpayload])
+
+Makefile.am:
+if GL_COND_OBJ_GETPAYLOAD
+lib_SOURCES += getpayload.c
+endif
+
+Include:
+<math.h>
+
+Link:
+$(GETPAYLOAD_LIBM)
+
+License:
+LGPL
+
+Maintainer:
+all
diff --git a/modules/math b/modules/math
index 70baab7586..b6a15f6d68 100644
--- a/modules/math
+++ b/modules/math
@@ -75,6 +75,7 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
-e 's/@''GNULIB_FREXPF''@/$(GNULIB_FREXPF)/g' \
-e 's/@''GNULIB_FREXP''@/$(GNULIB_FREXP)/g' \
-e 's/@''GNULIB_FREXPL''@/$(GNULIB_FREXPL)/g' \
+ -e 's/@''GNULIB_GETPAYLOAD''@/$(GNULIB_GETPAYLOAD)/g' \
-e 's/@''GNULIB_HYPOT''@/$(GNULIB_HYPOT)/g' \
-e 's/@''GNULIB_HYPOTF''@/$(GNULIB_HYPOTF)/g' \
-e 's/@''GNULIB_HYPOTL''@/$(GNULIB_HYPOTL)/g' \
@@ -176,6 +177,7 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
-e 's|@''HAVE_FMODF''@|$(HAVE_FMODF)|g' \
-e 's|@''HAVE_FMODL''@|$(HAVE_FMODL)|g' \
-e 's|@''HAVE_FREXPF''@|$(HAVE_FREXPF)|g' \
+ -e 's|@''HAVE_GETPAYLOAD''@|$(HAVE_GETPAYLOAD)|g' \
-e 's|@''HAVE_HYPOTF''@|$(HAVE_HYPOTF)|g' \
-e 's|@''HAVE_HYPOTL''@|$(HAVE_HYPOTL)|g' \
-e 's|@''HAVE_ILOGB''@|$(HAVE_ILOGB)|g' \
@@ -289,6 +291,7 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
-e 's|@''REPLACE_FREXPF''@|$(REPLACE_FREXPF)|g' \
-e 's|@''REPLACE_FREXP''@|$(REPLACE_FREXP)|g' \
-e 's|@''REPLACE_FREXPL''@|$(REPLACE_FREXPL)|g' \
+ -e 's|@''REPLACE_GETPAYLOAD''@|$(REPLACE_GETPAYLOAD)|g' \
-e 's|@''REPLACE_HUGE_VAL''@|$(REPLACE_HUGE_VAL)|g' \
-e 's|@''REPLACE_HYPOT''@|$(REPLACE_HYPOT)|g' \
-e 's|@''REPLACE_HYPOTF''@|$(REPLACE_HYPOTF)|g' \
--
2.34.1
[-- Attachment #3: 0002-getpayload-Add-tests.patch --]
[-- Type: text/x-patch, Size: 4451 bytes --]
From 97313e9122e3f9780f6d259361f5e9e495b6d4eb Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Wed, 17 Apr 2024 10:58:47 +0200
Subject: [PATCH 2/6] getpayload: Add tests.
* tests/test-getpayload.c: New file.
* modules/getpayload-tests: New file.
---
ChangeLog | 4 ++
modules/getpayload-tests | 18 +++++++
tests/test-getpayload.c | 112 +++++++++++++++++++++++++++++++++++++++
3 files changed, 134 insertions(+)
create mode 100644 modules/getpayload-tests
create mode 100644 tests/test-getpayload.c
diff --git a/ChangeLog b/ChangeLog
index 6fbcff9835..495ea4d996 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2024-04-17 Bruno Haible <bruno@clisp.org>
+ getpayload: Add tests.
+ * tests/test-getpayload.c: New file.
+ * modules/getpayload-tests: New file.
+
getpayload: New module.
* lib/math.in.h (getpayload): New declaration.
* lib/getpayload.c: New file.
diff --git a/modules/getpayload-tests b/modules/getpayload-tests
new file mode 100644
index 0000000000..d56192d63b
--- /dev/null
+++ b/modules/getpayload-tests
@@ -0,0 +1,18 @@
+Files:
+tests/test-getpayload.c
+tests/minus-zero.h
+tests/infinity.h
+tests/signature.h
+tests/macros.h
+
+Depends-on:
+setpayload
+setpayloadsig
+signed-snan
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-getpayload
+check_PROGRAMS += test-getpayload
+test_getpayload_LDADD = $(LDADD) @GETPAYLOAD_LIBM@ $(SETPAYLOAD_LIBM) $(SETPAYLOADSIG_LIBM)
diff --git a/tests/test-getpayload.c b/tests/test-getpayload.c
new file mode 100644
index 0000000000..a6d9d940bd
--- /dev/null
+++ b/tests/test-getpayload.c
@@ -0,0 +1,112 @@
+/* Test getpayload.
+ Copyright 2024 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include <math.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (getpayload, double, (const double *));
+
+#include "minus-zero.h"
+#include "infinity.h"
+#include "signed-snan.h"
+#include "macros.h"
+
+#define PAYLOAD_BITS (53 - 2) /* = (DBL_MANT_DIG - 2) */
+
+int
+main ()
+{
+ double arg;
+ double ret;
+
+ /* Test non-NaN arguments. */
+
+ arg = 2.718281828459045;
+ ret = getpayload (&arg);
+ ASSERT (ret == -1.0);
+
+ arg = -3.141592653589793;
+ ret = getpayload (&arg);
+ ASSERT (ret == -1.0);
+
+ arg = 0.0;
+ ret = getpayload (&arg);
+ ASSERT (ret == -1.0);
+
+ arg = minus_zerod;
+ ret = getpayload (&arg);
+ ASSERT (ret == -1.0);
+
+ arg = Infinityd ();
+ ret = getpayload (&arg);
+ ASSERT (ret == -1.0);
+
+ arg = - Infinityd ();
+ ret = getpayload (&arg);
+ ASSERT (ret == -1.0);
+
+ /* Test quiet NaNs. */
+ {
+ int i;
+ double p;
+
+ for (i = 0, p = 1.0; i < PAYLOAD_BITS; i++, p *= 2.0)
+ {
+ ASSERT (setpayload (&arg, p) == 0);
+ ret = getpayload (&arg);
+ ASSERT (ret == p);
+ /* Test quiet NaNs with sign bit == 1. */
+ arg = - arg;
+ ret = getpayload (&arg);
+ ASSERT (ret == p);
+ }
+
+ p = 1320699239819071.0;
+ ASSERT (setpayload (&arg, p) == 0);
+ ret = getpayload (&arg);
+ ASSERT (ret == p);
+ }
+
+ /* Test signalling NaNs. */
+ {
+ int i;
+ double p;
+
+ for (i = 0, p = 1.0; i < PAYLOAD_BITS; i++, p *= 2.0)
+ {
+ ASSERT (setpayloadsig (&arg, p) == 0);
+ ret = getpayload (&arg);
+ ASSERT (ret == p);
+ }
+
+ p = 1320699239819071.0;
+ ASSERT (setpayloadsig (&arg, p) == 0);
+ ret = getpayload (&arg);
+ ASSERT (ret == p);
+
+ /* Test signalling NaNs with sign bit == 1. */
+ memory_double pos_arg = memory_positive_SNaNd ();
+ memory_double neg_arg = memory_negative_SNaNd ();
+ double pos_ret = getpayload (&pos_arg.value);
+ double neg_ret = getpayload (&neg_arg.value);
+ ASSERT (neg_ret == pos_ret);
+ }
+
+ return 0;
+}
--
2.34.1
[-- Attachment #4: 0003-getpayloadf-New-module.patch --]
[-- Type: text/x-patch, Size: 10731 bytes --]
From 282b03a5af7553cd988b91e6380c228a66bfa6c1 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Wed, 17 Apr 2024 11:02:52 +0200
Subject: [PATCH 3/6] getpayloadf: New module.
* lib/math.in.h (getpayloadf): New declaration.
* lib/getpayloadf.c: New file.
* m4/math_h.m4 (gl_MATH_H): Test whether getpayloadf is declared.
(gl_MATH_H_REQUIRE_DEFAULTS): Initialize GNULIB_GETPAYLOADF.
(gl_MATH_H_DEFAULTS): Initialize HAVE_GETPAYLOADF, REPLACE_GETPAYLOADF.
* modules/math (Makefile.am): Substitute GNULIB_GETPAYLOADF,
HAVE_GETPAYLOADF, REPLACE_GETPAYLOADF.
* modules/getpayloadf: New file.
* doc/posix-functions/getpayloadf.texi: Mention the new module and the
glibc bug.
---
ChangeLog | 14 ++++++++
doc/posix-functions/getpayloadf.texi | 12 ++++---
lib/getpayloadf.c | 54 ++++++++++++++++++++++++++++
lib/math.in.h | 23 ++++++++++++
m4/math_h.m4 | 7 ++--
modules/getpayloadf | 37 +++++++++++++++++++
modules/math | 3 ++
7 files changed, 144 insertions(+), 6 deletions(-)
create mode 100644 lib/getpayloadf.c
create mode 100644 modules/getpayloadf
diff --git a/ChangeLog b/ChangeLog
index 495ea4d996..6f97325216 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2024-04-17 Bruno Haible <bruno@clisp.org>
+
+ getpayloadf: New module.
+ * lib/math.in.h (getpayloadf): New declaration.
+ * lib/getpayloadf.c: New file.
+ * m4/math_h.m4 (gl_MATH_H): Test whether getpayloadf is declared.
+ (gl_MATH_H_REQUIRE_DEFAULTS): Initialize GNULIB_GETPAYLOADF.
+ (gl_MATH_H_DEFAULTS): Initialize HAVE_GETPAYLOADF, REPLACE_GETPAYLOADF.
+ * modules/math (Makefile.am): Substitute GNULIB_GETPAYLOADF,
+ HAVE_GETPAYLOADF, REPLACE_GETPAYLOADF.
+ * modules/getpayloadf: New file.
+ * doc/posix-functions/getpayloadf.texi: Mention the new module and the
+ glibc bug.
+
2024-04-17 Bruno Haible <bruno@clisp.org>
getpayload: Add tests.
diff --git a/doc/posix-functions/getpayloadf.texi b/doc/posix-functions/getpayloadf.texi
index 39bd40ead9..98eecf0109 100644
--- a/doc/posix-functions/getpayloadf.texi
+++ b/doc/posix-functions/getpayloadf.texi
@@ -10,15 +10,19 @@
@url{https://www.gnu.org/software/libc/manual/html_node/FP-Bit-Twiddling.html}.
@end ifnotinfo
-Gnulib module: ---
+Gnulib module: getpayloadf
Portability problems fixed by Gnulib:
@itemize
+@item
+This function is missing on all non-glibc platforms:
+glibc 2.24, macOS 11.1, FreeBSD 14.0, NetBSD 10.0, OpenBSD 6.7, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, Solaris 11.4, Cygwin 2.9, mingw, MSVC 14, Android 9.0.
+@item
+This function returns a wrong result for non-NaN arguments on some platforms:
+@c https://sourceware.org/bugzilla/show_bug.cgi?id=26073
+glibc 2.31.
@end itemize
Portability problems not fixed by Gnulib:
@itemize
-@item
-This function is missing on all non-glibc platforms:
-glibc 2.24, macOS 11.1, FreeBSD 14.0, NetBSD 10.0, OpenBSD 6.7, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, Solaris 11.4, Cygwin 2.9, mingw, MSVC 14, Android 9.0.
@end itemize
diff --git a/lib/getpayloadf.c b/lib/getpayloadf.c
new file mode 100644
index 0000000000..6e24c55407
--- /dev/null
+++ b/lib/getpayloadf.c
@@ -0,0 +1,54 @@
+/* Extract the payload of a NaN 'float'.
+ Copyright 2024 Free Software Foundation, Inc.
+
+ This file is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible. */
+
+#include <config.h>
+
+/* Specification. */
+#include <math.h>
+
+#include <float.h>
+#include <stdint.h>
+#include <string.h>
+
+float
+getpayloadf (const float *value)
+{
+ if (isnanf (*value))
+ {
+#if FLT_MANT_DIG == 24
+ union { uint32_t i; float f; } x;
+# if 0
+ x.f = *value;
+# else
+ /* On 32-bit x86 processors, as well as on x86_64 processors with
+ CC="gcc -mfpmath=387", the evaluation of *value above is done
+ through an 'flds' instruction, which converts a signalling NaN to
+ a quiet NaN. See
+ <https://lists.gnu.org/archive/html/bug-gnulib/2023-10/msg00060.html>
+ for details. Use memcpy to avoid this. */
+ memcpy (&x.f, value, sizeof (float));
+# endif
+ int32_t payload = x.i & (((uint32_t) 1 << (FLT_MANT_DIG - 2)) - 1);
+ return payload;
+#else
+# error "Please port gnulib getpayloadf.c to your platform!"
+#endif
+ }
+ else
+ return -1.0f;
+}
diff --git a/lib/math.in.h b/lib/math.in.h
index 2e7dde2e07..7a59c8cf35 100644
--- a/lib/math.in.h
+++ b/lib/math.in.h
@@ -2774,6 +2774,29 @@ _GL_WARN_REAL_FLOATING_DECL (signbit);
#endif
+#if @GNULIB_GETPAYLOADF@
+# if @REPLACE_GETPAYLOADF@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef getpayloadf
+# define getpayloadf rpl_getpayloadf
+# endif
+_GL_FUNCDECL_RPL (getpayloadf, float, (const float *));
+_GL_CXXALIAS_RPL (getpayloadf, float, (const float *));
+# else
+# if !@HAVE_GETPAYLOADF@
+_GL_FUNCDECL_SYS (getpayloadf, float, (const float *));
+# endif
+_GL_CXXALIAS_SYS (getpayloadf, float, (const float *));
+# endif
+_GL_CXXALIASWARN (getpayloadf);
+#elif defined GNULIB_POSIXCHECK
+# undef getpayloadf
+# if HAVE_RAW_DECL_GETPAYLOADF
+_GL_WARN_ON_USE (getpayloadf, "getpayloadf is unportable - "
+ "use gnulib module getpayloadf for portability");
+# endif
+#endif
+
#if @GNULIB_GETPAYLOAD@
# if @REPLACE_GETPAYLOAD@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
diff --git a/m4/math_h.m4 b/m4/math_h.m4
index 370ea14051..12aafb7fe9 100644
--- a/m4/math_h.m4
+++ b/m4/math_h.m4
@@ -1,5 +1,5 @@
# math_h.m4
-# serial 133
+# serial 134
dnl Copyright (C) 2007-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,
@@ -44,7 +44,7 @@ AC_DEFUN_ONCE([gl_MATH_H]
expf expl exp2 exp2f exp2l expm1 expm1f expm1l
fabsf fabsl floorf floorl fma fmaf fmal
fmod fmodf fmodl frexpf frexpl
- getpayload
+ getpayload getpayloadf
hypotf hypotl
ilogb ilogbf ilogbl
ldexpf ldexpl
@@ -120,6 +120,7 @@ AC_DEFUN([gl_MATH_H_REQUIRE_DEFAULTS]
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FREXP])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FREXPL])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETPAYLOAD])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETPAYLOADF])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_HYPOT])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_HYPOTF])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_HYPOTL])
@@ -227,6 +228,7 @@ AC_DEFUN([gl_MATH_H_DEFAULTS]
HAVE_FMODL=1; AC_SUBST([HAVE_FMODL])
HAVE_FREXPF=1; AC_SUBST([HAVE_FREXPF])
HAVE_GETPAYLOAD=1; AC_SUBST([HAVE_GETPAYLOAD])
+ HAVE_GETPAYLOADF=1; AC_SUBST([HAVE_GETPAYLOADF])
HAVE_HYPOTF=1; AC_SUBST([HAVE_HYPOTF])
HAVE_HYPOTL=1; AC_SUBST([HAVE_HYPOTL])
HAVE_ILOGB=1; AC_SUBST([HAVE_ILOGB])
@@ -337,6 +339,7 @@ AC_DEFUN([gl_MATH_H_DEFAULTS]
REPLACE_FREXP=0; AC_SUBST([REPLACE_FREXP])
REPLACE_FREXPL=0; AC_SUBST([REPLACE_FREXPL])
REPLACE_GETPAYLOAD=0; AC_SUBST([REPLACE_GETPAYLOAD])
+ REPLACE_GETPAYLOADF=0; AC_SUBST([REPLACE_GETPAYLOADF])
REPLACE_HUGE_VAL=0; AC_SUBST([REPLACE_HUGE_VAL])
REPLACE_HYPOT=0; AC_SUBST([REPLACE_HYPOT])
REPLACE_HYPOTF=0; AC_SUBST([REPLACE_HYPOTF])
diff --git a/modules/getpayloadf b/modules/getpayloadf
new file mode 100644
index 0000000000..a330b4f87a
--- /dev/null
+++ b/modules/getpayloadf
@@ -0,0 +1,37 @@
+Description:
+getpayloadf function: extract the payload of a NaN
+
+Files:
+lib/getpayloadf.c
+m4/mathfunc.m4
+m4/getpayload.m4
+
+Depends-on:
+math
+extensions
+float [test $HAVE_GETPAYLOADF = 0 || test $REPLACE_GETPAYLOADF = 1]
+stdint [test $HAVE_GETPAYLOADF = 0 || test $REPLACE_GETPAYLOADF = 1]
+isnanf [test $HAVE_GETPAYLOADF = 0 || test $REPLACE_GETPAYLOADF = 1]
+
+configure.ac:
+gl_FUNC_GETPAYLOADF
+gl_CONDITIONAL([GL_COND_OBJ_GETPAYLOADF],
+ [test $HAVE_GETPAYLOADF = 0 || test $REPLACE_GETPAYLOADF = 1])
+gl_MATH_MODULE_INDICATOR([getpayloadf])
+
+Makefile.am:
+if GL_COND_OBJ_GETPAYLOADF
+lib_SOURCES += getpayloadf.c
+endif
+
+Include:
+<math.h>
+
+Link:
+$(GETPAYLOADF_LIBM)
+
+License:
+LGPL
+
+Maintainer:
+all
diff --git a/modules/math b/modules/math
index b6a15f6d68..a8c9646124 100644
--- a/modules/math
+++ b/modules/math
@@ -76,6 +76,7 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
-e 's/@''GNULIB_FREXP''@/$(GNULIB_FREXP)/g' \
-e 's/@''GNULIB_FREXPL''@/$(GNULIB_FREXPL)/g' \
-e 's/@''GNULIB_GETPAYLOAD''@/$(GNULIB_GETPAYLOAD)/g' \
+ -e 's/@''GNULIB_GETPAYLOADF''@/$(GNULIB_GETPAYLOADF)/g' \
-e 's/@''GNULIB_HYPOT''@/$(GNULIB_HYPOT)/g' \
-e 's/@''GNULIB_HYPOTF''@/$(GNULIB_HYPOTF)/g' \
-e 's/@''GNULIB_HYPOTL''@/$(GNULIB_HYPOTL)/g' \
@@ -178,6 +179,7 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
-e 's|@''HAVE_FMODL''@|$(HAVE_FMODL)|g' \
-e 's|@''HAVE_FREXPF''@|$(HAVE_FREXPF)|g' \
-e 's|@''HAVE_GETPAYLOAD''@|$(HAVE_GETPAYLOAD)|g' \
+ -e 's|@''HAVE_GETPAYLOADF''@|$(HAVE_GETPAYLOADF)|g' \
-e 's|@''HAVE_HYPOTF''@|$(HAVE_HYPOTF)|g' \
-e 's|@''HAVE_HYPOTL''@|$(HAVE_HYPOTL)|g' \
-e 's|@''HAVE_ILOGB''@|$(HAVE_ILOGB)|g' \
@@ -292,6 +294,7 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
-e 's|@''REPLACE_FREXP''@|$(REPLACE_FREXP)|g' \
-e 's|@''REPLACE_FREXPL''@|$(REPLACE_FREXPL)|g' \
-e 's|@''REPLACE_GETPAYLOAD''@|$(REPLACE_GETPAYLOAD)|g' \
+ -e 's|@''REPLACE_GETPAYLOADF''@|$(REPLACE_GETPAYLOADF)|g' \
-e 's|@''REPLACE_HUGE_VAL''@|$(REPLACE_HUGE_VAL)|g' \
-e 's|@''REPLACE_HYPOT''@|$(REPLACE_HYPOT)|g' \
-e 's|@''REPLACE_HYPOTF''@|$(REPLACE_HYPOTF)|g' \
--
2.34.1
[-- Attachment #5: 0004-getpayloadf-Add-tests.patch --]
[-- Type: text/x-patch, Size: 4484 bytes --]
From e32e13caaef5f0cf9d6fc47a042251832746b7b7 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Wed, 17 Apr 2024 11:03:53 +0200
Subject: [PATCH 4/6] getpayloadf: Add tests.
* tests/test-getpayloadf.c: New file.
* modules/getpayloadf-tests: New file.
---
ChangeLog | 4 ++
modules/getpayloadf-tests | 18 ++++++
tests/test-getpayloadf.c | 112 ++++++++++++++++++++++++++++++++++++++
3 files changed, 134 insertions(+)
create mode 100644 modules/getpayloadf-tests
create mode 100644 tests/test-getpayloadf.c
diff --git a/ChangeLog b/ChangeLog
index 6f97325216..863442a263 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2024-04-17 Bruno Haible <bruno@clisp.org>
+ getpayloadf: Add tests.
+ * tests/test-getpayloadf.c: New file.
+ * modules/getpayloadf-tests: New file.
+
getpayloadf: New module.
* lib/math.in.h (getpayloadf): New declaration.
* lib/getpayloadf.c: New file.
diff --git a/modules/getpayloadf-tests b/modules/getpayloadf-tests
new file mode 100644
index 0000000000..1901fc43f9
--- /dev/null
+++ b/modules/getpayloadf-tests
@@ -0,0 +1,18 @@
+Files:
+tests/test-getpayloadf.c
+tests/minus-zero.h
+tests/infinity.h
+tests/signature.h
+tests/macros.h
+
+Depends-on:
+setpayloadf
+setpayloadsigf
+signed-snan
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-getpayloadf
+check_PROGRAMS += test-getpayloadf
+test_getpayloadf_LDADD = $(LDADD) @GETPAYLOADF_LIBM@ $(SETPAYLOADF_LIBM) $(SETPAYLOADSIGF_LIBM)
diff --git a/tests/test-getpayloadf.c b/tests/test-getpayloadf.c
new file mode 100644
index 0000000000..f0ec047235
--- /dev/null
+++ b/tests/test-getpayloadf.c
@@ -0,0 +1,112 @@
+/* Test getpayloadf.
+ Copyright 2024 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include <math.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (getpayloadf, float, (const float *));
+
+#include "minus-zero.h"
+#include "infinity.h"
+#include "signed-snan.h"
+#include "macros.h"
+
+#define PAYLOAD_BITS (24 - 2) /* = (FLT_MANT_DIG - 2) */
+
+int
+main ()
+{
+ float arg;
+ float ret;
+
+ /* Test non-NaN arguments. */
+
+ arg = 2.718281828459045f;
+ ret = getpayloadf (&arg);
+ ASSERT (ret == -1.0f);
+
+ arg = -3.141592653589793f;
+ ret = getpayloadf (&arg);
+ ASSERT (ret == -1.0f);
+
+ arg = 0.0f;
+ ret = getpayloadf (&arg);
+ ASSERT (ret == -1.0f);
+
+ arg = minus_zerof;
+ ret = getpayloadf (&arg);
+ ASSERT (ret == -1.0f);
+
+ arg = Infinityf ();
+ ret = getpayloadf (&arg);
+ ASSERT (ret == -1.0f);
+
+ arg = - Infinityf ();
+ ret = getpayloadf (&arg);
+ ASSERT (ret == -1.0f);
+
+ /* Test quiet NaNs. */
+ {
+ int i;
+ float p;
+
+ for (i = 0, p = 1.0f; i < PAYLOAD_BITS; i++, p *= 2.0f)
+ {
+ ASSERT (setpayloadf (&arg, p) == 0);
+ ret = getpayloadf (&arg);
+ ASSERT (ret == p);
+ /* Test quiet NaNs with sign bit == 1. */
+ arg = - arg;
+ ret = getpayloadf (&arg);
+ ASSERT (ret == p);
+ }
+
+ p = 2300902.0f;
+ ASSERT (setpayloadf (&arg, p) == 0);
+ ret = getpayloadf (&arg);
+ ASSERT (ret == p);
+ }
+
+ /* Test signalling NaNs. */
+ {
+ int i;
+ float p;
+
+ for (i = 0, p = 1.0f; i < PAYLOAD_BITS; i++, p *= 2.0f)
+ {
+ ASSERT (setpayloadsigf (&arg, p) == 0);
+ ret = getpayloadf (&arg);
+ ASSERT (ret == p);
+ }
+
+ p = 2300902.0f;
+ ASSERT (setpayloadsigf (&arg, p) == 0);
+ ret = getpayloadf (&arg);
+ ASSERT (ret == p);
+
+ /* Test signalling NaNs with sign bit == 1. */
+ memory_float pos_arg = memory_positive_SNaNf ();
+ memory_float neg_arg = memory_negative_SNaNf ();
+ float pos_ret = getpayloadf (&pos_arg.value);
+ float neg_ret = getpayloadf (&neg_arg.value);
+ ASSERT (neg_ret == pos_ret);
+ }
+
+ return 0;
+}
--
2.34.1
[-- Attachment #6: 0005-getpayloadl-New-module.patch --]
[-- Type: text/x-patch, Size: 13046 bytes --]
From 63f3bcdc9a42de17310dc636e031385a0feeaeff Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Wed, 17 Apr 2024 11:08:40 +0200
Subject: [PATCH 5/6] getpayloadl: New module.
* lib/math.in.h (getpayloadl): New declaration.
* lib/getpayloadl.c: New file.
* m4/math_h.m4 (gl_MATH_H): Test whether getpayloadl is declared.
(gl_MATH_H_REQUIRE_DEFAULTS): Initialize GNULIB_GETPAYLOADL.
(gl_MATH_H_DEFAULTS): Initialize HAVE_GETPAYLOADL, REPLACE_GETPAYLOADL.
* modules/math (Makefile.am): Substitute GNULIB_GETPAYLOADL,
HAVE_GETPAYLOADL, REPLACE_GETPAYLOADL.
* modules/getpayloadl: New file.
* doc/posix-functions/getpayloadl.texi: Mention the new module and the
glibc bug.
---
ChangeLog | 14 ++++
doc/posix-functions/getpayloadl.texi | 12 ++--
lib/getpayloadl.c | 100 +++++++++++++++++++++++++++
lib/math.in.h | 23 ++++++
m4/math_h.m4 | 7 +-
modules/getpayloadl | 40 +++++++++++
modules/math | 3 +
7 files changed, 193 insertions(+), 6 deletions(-)
create mode 100644 lib/getpayloadl.c
create mode 100644 modules/getpayloadl
diff --git a/ChangeLog b/ChangeLog
index 863442a263..bcc40cb255 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2024-04-17 Bruno Haible <bruno@clisp.org>
+
+ getpayloadl: New module.
+ * lib/math.in.h (getpayloadl): New declaration.
+ * lib/getpayloadl.c: New file.
+ * m4/math_h.m4 (gl_MATH_H): Test whether getpayloadl is declared.
+ (gl_MATH_H_REQUIRE_DEFAULTS): Initialize GNULIB_GETPAYLOADL.
+ (gl_MATH_H_DEFAULTS): Initialize HAVE_GETPAYLOADL, REPLACE_GETPAYLOADL.
+ * modules/math (Makefile.am): Substitute GNULIB_GETPAYLOADL,
+ HAVE_GETPAYLOADL, REPLACE_GETPAYLOADL.
+ * modules/getpayloadl: New file.
+ * doc/posix-functions/getpayloadl.texi: Mention the new module and the
+ glibc bug.
+
2024-04-17 Bruno Haible <bruno@clisp.org>
getpayloadf: Add tests.
diff --git a/doc/posix-functions/getpayloadl.texi b/doc/posix-functions/getpayloadl.texi
index b3f6471a67..8b1273b367 100644
--- a/doc/posix-functions/getpayloadl.texi
+++ b/doc/posix-functions/getpayloadl.texi
@@ -10,15 +10,19 @@
@url{https://www.gnu.org/software/libc/manual/html_node/FP-Bit-Twiddling.html}.
@end ifnotinfo
-Gnulib module: ---
+Gnulib module: getpayloadl
Portability problems fixed by Gnulib:
@itemize
+@item
+This function is missing on all non-glibc platforms:
+glibc 2.24, macOS 11.1, FreeBSD 14.0, NetBSD 10.0, OpenBSD 6.7, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, Solaris 11.4, Cygwin 2.9, mingw, MSVC 14, Android 9.0.
+@item
+This function returns a wrong result for non-NaN arguments on some platforms:
+@c https://sourceware.org/bugzilla/show_bug.cgi?id=26073
+glibc 2.31.
@end itemize
Portability problems not fixed by Gnulib:
@itemize
-@item
-This function is missing on all non-glibc platforms:
-glibc 2.24, macOS 11.1, FreeBSD 14.0, NetBSD 10.0, OpenBSD 6.7, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, Solaris 11.4, Cygwin 2.9, mingw, MSVC 14, Android 9.0.
@end itemize
diff --git a/lib/getpayloadl.c b/lib/getpayloadl.c
new file mode 100644
index 0000000000..6eefb56182
--- /dev/null
+++ b/lib/getpayloadl.c
@@ -0,0 +1,100 @@
+/* Extract the payload of a NaN 'long double'.
+ Copyright 2024 Free Software Foundation, Inc.
+
+ This file is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible. */
+
+#include <config.h>
+
+/* Specification. */
+#include <math.h>
+
+#if HAVE_SAME_LONG_DOUBLE_AS_DOUBLE
+
+long double
+getpayloadl (const long double *value)
+{
+ return getpayload ((const double *) value);
+}
+
+#else
+
+# include <float.h>
+# include <stdint.h>
+
+# include "snan.h"
+
+/* 2^(LDBL_MANT_DIG-1). */
+# define TWO_LDBL_MANT_DIG \
+ ((long double) (1U << ((LDBL_MANT_DIG - 1) / 4)) \
+ * (long double) (1U << ((LDBL_MANT_DIG - 1 + 1) / 4)) \
+ * (long double) (1U << ((LDBL_MANT_DIG - 1 + 2) / 4)) \
+ * (long double) (1U << ((LDBL_MANT_DIG - 1 + 3) / 4)))
+
+long double
+getpayloadl (const long double *value)
+{
+ if (isnanl (*value))
+ {
+# if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 106 || LDBL_MANT_DIG == 113) \
+ && defined LDBL_EXPBIT0_WORD && defined LDBL_EXPBIT0_BIT
+ memory_long_double x;
+ x.value = *value;
+# if LDBL_MANT_DIG == 64 /* on i386, x86_64, ia64, m68k */
+ int64_t payload;
+# if LDBL_EXPBIT0_WORD == 2 && LDBL_EXPBIT0_BIT == 0 /* on i386, x86_64, ia64 */
+ payload = ((uint64_t) (x.word[1] & 0x3FFFFFFFU) << 32) | x.word[0];
+# elif LDBL_EXPBIT0_WORD == 0 && LDBL_EXPBIT0_BIT == 16 /* on m68k */
+ payload = ((uint64_t) (x.word[1] & 0x3FFFFFFFU) << 32) | x.word[2];
+# else
+# error "Please port gnulib getpayloadl.c to your platform!"
+# endif
+ return payload;
+# endif
+# if LDBL_MANT_DIG == 106 /* on powerpc, powerpc64, powerpc64le */
+ int64_t payload;
+# if LDBL_EXPBIT0_BIT == 20
+ payload = ((uint64_t) (x.word[LDBL_EXPBIT0_WORD] & 0x0007FFFFU) << 32)
+ | x.word[LDBL_EXPBIT0_WORD + (LDBL_EXPBIT0_WORD == 0 ? 1 : -1)];
+# else
+# error "Please port gnulib getpayloadl.c to your platform!"
+# endif
+ return payload;
+# endif
+# if LDBL_MANT_DIG == 113 /* on alpha, arm64, loongarch64, mips64, riscv64, s390x, sparc64 */
+# if LDBL_EXPBIT0_BIT == 16
+ memory_long_double pl;
+ pl.value = TWO_LDBL_MANT_DIG;
+ pl.word[LDBL_EXPBIT0_WORD] |= x.word[LDBL_EXPBIT0_WORD] & 0x00007FFFU;
+ pl.word[LDBL_EXPBIT0_WORD + (LDBL_EXPBIT0_WORD == 0 ? 1 : -1)] =
+ x.word[LDBL_EXPBIT0_WORD + (LDBL_EXPBIT0_WORD == 0 ? 1 : -1)];
+ pl.word[LDBL_EXPBIT0_WORD + (LDBL_EXPBIT0_WORD == 0 ? 2 : -2)] =
+ x.word[LDBL_EXPBIT0_WORD + (LDBL_EXPBIT0_WORD == 0 ? 2 : -2)];
+ pl.word[LDBL_EXPBIT0_WORD + (LDBL_EXPBIT0_WORD == 0 ? 3 : -3)] =
+ x.word[LDBL_EXPBIT0_WORD + (LDBL_EXPBIT0_WORD == 0 ? 3 : -3)];
+ return pl.value - TWO_LDBL_MANT_DIG;
+# else
+# error "Please port gnulib getpayloadl.c to your platform!"
+# endif
+# endif
+# else
+# error "Please port gnulib getpayloadl.c to your platform!"
+# endif
+ }
+ else
+ return -1.0L;
+}
+
+#endif
diff --git a/lib/math.in.h b/lib/math.in.h
index 7a59c8cf35..84b743e7ab 100644
--- a/lib/math.in.h
+++ b/lib/math.in.h
@@ -2820,6 +2820,29 @@ _GL_WARN_ON_USE (getpayload, "getpayload is unportable - "
# endif
#endif
+#if @GNULIB_GETPAYLOADL@
+# if @REPLACE_GETPAYLOADL@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef getpayloadl
+# define getpayloadl rpl_getpayloadl
+# endif
+_GL_FUNCDECL_RPL (getpayloadl, long double, (const long double *));
+_GL_CXXALIAS_RPL (getpayloadl, long double, (const long double *));
+# else
+# if !@HAVE_GETPAYLOADL@
+_GL_FUNCDECL_SYS (getpayloadl, long double, (const long double *));
+# endif
+_GL_CXXALIAS_SYS (getpayloadl, long double, (const long double *));
+# endif
+_GL_CXXALIASWARN (getpayloadl);
+#elif defined GNULIB_POSIXCHECK
+# undef getpayloadl
+# if HAVE_RAW_DECL_GETPAYLOADL
+_GL_WARN_ON_USE (getpayloadl, "getpayloadl is unportable - "
+ "use gnulib module getpayloadl for portability");
+# endif
+#endif
+
#if @GNULIB_SETPAYLOADF@
# if !@HAVE_SETPAYLOADF@
diff --git a/m4/math_h.m4 b/m4/math_h.m4
index 12aafb7fe9..217c4d225d 100644
--- a/m4/math_h.m4
+++ b/m4/math_h.m4
@@ -1,5 +1,5 @@
# math_h.m4
-# serial 134
+# serial 135
dnl Copyright (C) 2007-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,
@@ -44,7 +44,7 @@ AC_DEFUN_ONCE([gl_MATH_H]
expf expl exp2 exp2f exp2l expm1 expm1f expm1l
fabsf fabsl floorf floorl fma fmaf fmal
fmod fmodf fmodl frexpf frexpl
- getpayload getpayloadf
+ getpayload getpayloadf getpayloadl
hypotf hypotl
ilogb ilogbf ilogbl
ldexpf ldexpl
@@ -121,6 +121,7 @@ AC_DEFUN([gl_MATH_H_REQUIRE_DEFAULTS]
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FREXPL])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETPAYLOAD])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETPAYLOADF])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETPAYLOADL])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_HYPOT])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_HYPOTF])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_HYPOTL])
@@ -229,6 +230,7 @@ AC_DEFUN([gl_MATH_H_DEFAULTS]
HAVE_FREXPF=1; AC_SUBST([HAVE_FREXPF])
HAVE_GETPAYLOAD=1; AC_SUBST([HAVE_GETPAYLOAD])
HAVE_GETPAYLOADF=1; AC_SUBST([HAVE_GETPAYLOADF])
+ HAVE_GETPAYLOADL=1; AC_SUBST([HAVE_GETPAYLOADL])
HAVE_HYPOTF=1; AC_SUBST([HAVE_HYPOTF])
HAVE_HYPOTL=1; AC_SUBST([HAVE_HYPOTL])
HAVE_ILOGB=1; AC_SUBST([HAVE_ILOGB])
@@ -340,6 +342,7 @@ AC_DEFUN([gl_MATH_H_DEFAULTS]
REPLACE_FREXPL=0; AC_SUBST([REPLACE_FREXPL])
REPLACE_GETPAYLOAD=0; AC_SUBST([REPLACE_GETPAYLOAD])
REPLACE_GETPAYLOADF=0; AC_SUBST([REPLACE_GETPAYLOADF])
+ REPLACE_GETPAYLOADL=0; AC_SUBST([REPLACE_GETPAYLOADL])
REPLACE_HUGE_VAL=0; AC_SUBST([REPLACE_HUGE_VAL])
REPLACE_HYPOT=0; AC_SUBST([REPLACE_HYPOT])
REPLACE_HYPOTF=0; AC_SUBST([REPLACE_HYPOTF])
diff --git a/modules/getpayloadl b/modules/getpayloadl
new file mode 100644
index 0000000000..3ddd0a57ef
--- /dev/null
+++ b/modules/getpayloadl
@@ -0,0 +1,40 @@
+Description:
+getpayloadl function: extract the payload of a NaN
+
+Files:
+lib/getpayloadl.c
+m4/mathfunc.m4
+m4/getpayload.m4
+m4/exponentl.m4
+
+Depends-on:
+math
+extensions
+getpayload [{ test $HAVE_GETPAYLOADL = 0 || test $REPLACE_GETPAYLOADL = 1; } && test $HAVE_SAME_LONG_DOUBLE_AS_DOUBLE = 1]
+float [{ test $HAVE_GETPAYLOADL = 0 || test $REPLACE_GETPAYLOADL = 1; } && test $HAVE_SAME_LONG_DOUBLE_AS_DOUBLE = 0]
+stdint [{ test $HAVE_GETPAYLOADL = 0 || test $REPLACE_GETPAYLOADL = 1; } && test $HAVE_SAME_LONG_DOUBLE_AS_DOUBLE = 0]
+isnanl [{ test $HAVE_GETPAYLOADL = 0 || test $REPLACE_GETPAYLOADL = 1; } && test $HAVE_SAME_LONG_DOUBLE_AS_DOUBLE = 0]
+snan [{ test $HAVE_GETPAYLOADL = 0 || test $REPLACE_GETPAYLOADL = 1; } && test $HAVE_SAME_LONG_DOUBLE_AS_DOUBLE = 0]
+
+configure.ac:
+gl_FUNC_GETPAYLOADL
+gl_CONDITIONAL([GL_COND_OBJ_GETPAYLOADL],
+ [test $HAVE_GETPAYLOADL = 0 || test $REPLACE_GETPAYLOADL = 1])
+gl_MATH_MODULE_INDICATOR([getpayloadl])
+
+Makefile.am:
+if GL_COND_OBJ_GETPAYLOADL
+lib_SOURCES += getpayloadl.c
+endif
+
+Include:
+<math.h>
+
+Link:
+$(GETPAYLOADL_LIBM)
+
+License:
+LGPL
+
+Maintainer:
+all
diff --git a/modules/math b/modules/math
index a8c9646124..8c853f0979 100644
--- a/modules/math
+++ b/modules/math
@@ -77,6 +77,7 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
-e 's/@''GNULIB_FREXPL''@/$(GNULIB_FREXPL)/g' \
-e 's/@''GNULIB_GETPAYLOAD''@/$(GNULIB_GETPAYLOAD)/g' \
-e 's/@''GNULIB_GETPAYLOADF''@/$(GNULIB_GETPAYLOADF)/g' \
+ -e 's/@''GNULIB_GETPAYLOADL''@/$(GNULIB_GETPAYLOADL)/g' \
-e 's/@''GNULIB_HYPOT''@/$(GNULIB_HYPOT)/g' \
-e 's/@''GNULIB_HYPOTF''@/$(GNULIB_HYPOTF)/g' \
-e 's/@''GNULIB_HYPOTL''@/$(GNULIB_HYPOTL)/g' \
@@ -180,6 +181,7 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
-e 's|@''HAVE_FREXPF''@|$(HAVE_FREXPF)|g' \
-e 's|@''HAVE_GETPAYLOAD''@|$(HAVE_GETPAYLOAD)|g' \
-e 's|@''HAVE_GETPAYLOADF''@|$(HAVE_GETPAYLOADF)|g' \
+ -e 's|@''HAVE_GETPAYLOADL''@|$(HAVE_GETPAYLOADL)|g' \
-e 's|@''HAVE_HYPOTF''@|$(HAVE_HYPOTF)|g' \
-e 's|@''HAVE_HYPOTL''@|$(HAVE_HYPOTL)|g' \
-e 's|@''HAVE_ILOGB''@|$(HAVE_ILOGB)|g' \
@@ -295,6 +297,7 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
-e 's|@''REPLACE_FREXPL''@|$(REPLACE_FREXPL)|g' \
-e 's|@''REPLACE_GETPAYLOAD''@|$(REPLACE_GETPAYLOAD)|g' \
-e 's|@''REPLACE_GETPAYLOADF''@|$(REPLACE_GETPAYLOADF)|g' \
+ -e 's|@''REPLACE_GETPAYLOADL''@|$(REPLACE_GETPAYLOADL)|g' \
-e 's|@''REPLACE_HUGE_VAL''@|$(REPLACE_HUGE_VAL)|g' \
-e 's|@''REPLACE_HYPOT''@|$(REPLACE_HYPOT)|g' \
-e 's|@''REPLACE_HYPOTF''@|$(REPLACE_HYPOTF)|g' \
--
2.34.1
[-- Attachment #7: 0006-getpayloadl-Add-tests.patch --]
[-- Type: text/x-patch, Size: 4923 bytes --]
From 507b790ed13750b4c81afff56f403d2aeac4ca72 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Wed, 17 Apr 2024 11:09:13 +0200
Subject: [PATCH 6/6] getpayloadl: Add tests.
* tests/test-getpayloadl.c: New file.
* modules/getpayloadl-tests: New file.
---
ChangeLog | 4 ++
modules/getpayloadl-tests | 18 ++++++
tests/test-getpayloadl.c | 119 ++++++++++++++++++++++++++++++++++++++
3 files changed, 141 insertions(+)
create mode 100644 modules/getpayloadl-tests
create mode 100644 tests/test-getpayloadl.c
diff --git a/ChangeLog b/ChangeLog
index bcc40cb255..e6b4eff89b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2024-04-17 Bruno Haible <bruno@clisp.org>
+ getpayloadl: Add tests.
+ * tests/test-getpayloadl.c: New file.
+ * modules/getpayloadl-tests: New file.
+
getpayloadl: New module.
* lib/math.in.h (getpayloadl): New declaration.
* lib/getpayloadl.c: New file.
diff --git a/modules/getpayloadl-tests b/modules/getpayloadl-tests
new file mode 100644
index 0000000000..02433a206d
--- /dev/null
+++ b/modules/getpayloadl-tests
@@ -0,0 +1,18 @@
+Files:
+tests/test-getpayloadl.c
+tests/minus-zero.h
+tests/infinity.h
+tests/signature.h
+tests/macros.h
+
+Depends-on:
+setpayloadl
+setpayloadsigl
+signed-snan
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-getpayloadl
+check_PROGRAMS += test-getpayloadl
+test_getpayloadl_LDADD = $(LDADD) @GETPAYLOADL_LIBM@ $(SETPAYLOADL_LIBM) $(SETPAYLOADSIGL_LIBM)
diff --git a/tests/test-getpayloadl.c b/tests/test-getpayloadl.c
new file mode 100644
index 0000000000..4aaa7c5c0c
--- /dev/null
+++ b/tests/test-getpayloadl.c
@@ -0,0 +1,119 @@
+/* Test getpayloadl.
+ Copyright 2024 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include <math.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (getpayloadl, long double, (const long double *));
+
+#include "minus-zero.h"
+#include "infinity.h"
+#include "signed-snan.h"
+#include "macros.h"
+
+#if defined __powerpc__ && LDBL_MANT_DIG == 106
+ /* This is PowerPC "double double", a pair of two doubles. NaN is represented
+ as the corresponding 64-bit IEEE value in the first double; the second is
+ irrelevant and therefore does not contain a payload. */
+# define PAYLOAD_BITS (DBL_MANT_DIG - 2)
+#else
+# define PAYLOAD_BITS (LDBL_MANT_DIG - 2)
+#endif
+
+int
+main ()
+{
+ long double arg;
+ long double ret;
+
+ /* Test non-NaN arguments. */
+
+ arg = 2.71828182845904523536028747135266249776L;
+ ret = getpayloadl (&arg);
+ ASSERT (ret == -1.0L);
+
+ arg = -3.1415926535897932384626433832795028842L;
+ ret = getpayloadl (&arg);
+ ASSERT (ret == -1.0L);
+
+ arg = 0.0L;
+ ret = getpayloadl (&arg);
+ ASSERT (ret == -1.0L);
+
+ arg = minus_zerol;
+ ret = getpayloadl (&arg);
+ ASSERT (ret == -1.0L);
+
+ arg = Infinityl ();
+ ret = getpayloadl (&arg);
+ ASSERT (ret == -1.0L);
+
+ arg = - Infinityl ();
+ ret = getpayloadl (&arg);
+ ASSERT (ret == -1.0L);
+
+ /* Test quiet NaNs. */
+ {
+ int i;
+ long double p;
+
+ for (i = 0, p = 1.0L; i < PAYLOAD_BITS; i++, p *= 2.0L)
+ {
+ ASSERT (setpayloadl (&arg, p) == 0);
+ ret = getpayloadl (&arg);
+ ASSERT (ret == p);
+ /* Test quiet NaNs with sign bit == 1. */
+ arg = - arg;
+ ret = getpayloadl (&arg);
+ ASSERT (ret == p);
+ }
+
+ p = 1320699239819071.0L;
+ ASSERT (setpayloadl (&arg, p) == 0);
+ ret = getpayloadl (&arg);
+ ASSERT (ret == p);
+ }
+
+ /* Test signalling NaNs. */
+ {
+ int i;
+ long double p;
+
+ for (i = 0, p = 1.0L; i < PAYLOAD_BITS; i++, p *= 2.0L)
+ {
+ ASSERT (setpayloadsigl (&arg, p) == 0);
+ ret = getpayloadl (&arg);
+ ASSERT (ret == p);
+ }
+
+ p = 1320699239819071.0L;
+ ASSERT (setpayloadsigl (&arg, p) == 0);
+ ret = getpayloadl (&arg);
+ ASSERT (ret == p);
+
+ /* Test signalling NaNs with sign bit == 1. */
+ memory_long_double pos_arg = memory_positive_SNaNl ();
+ memory_long_double neg_arg = memory_negative_SNaNl ();
+ long double pos_ret = getpayloadl (&pos_arg.value);
+ long double neg_ret = getpayloadl (&neg_arg.value);
+ ASSERT (neg_ret == pos_ret);
+ }
+
+ return 0;
+}
--
2.34.1
reply other threads:[~2024-04-17 13:57 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://lists.gnu.org/mailman/listinfo/bug-gnulib
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=13436243.RAW8MR3E7N@nimes \
--to=bruno@clisp.org \
--cc=bug-gnulib@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).