1
0
mirror of https://https.git.savannah.gnu.org/git/gnulib.git synced 2026-09-01 02:34:55 +00:00

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.
This commit is contained in:
Bruno Haible
2024-04-17 10:57:05 +02:00
parent 64a7072ee8
commit 20b8f23dca
8 changed files with 332 additions and 7 deletions
+15
View File
@@ -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.
+9 -5
View File
@@ -10,15 +10,19 @@ Documentation:@*
@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
@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.
@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
@end itemize
+54
View File
@@ -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;
}
+24
View File
@@ -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));
+183
View File
@@ -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])
])
+7 -2
View File
@@ -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])
+37
View File
@@ -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
+3
View File
@@ -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' \