From e53309da10a1ec7d5b47dbd9f561763f17f74fb8 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Tue, 16 Apr 2024 14:25:27 +0200 Subject: [PATCH] setpayload: New module. * lib/math.in.h (setpayload): New declaration. * lib/setpayload.c: New file. * m4/setpayload.m4: New file. * m4/math_h.m4 (gl_MATH_H): Test whether setpayload is declared. (gl_MATH_H_REQUIRE_DEFAULTS): Initialize GNULIB_SETPAYLOAD. (gl_MATH_H_DEFAULTS): Initialize HAVE_SETPAYLOAD. * modules/math (Makefile.am): Substitute GNULIB_SETPAYLOAD, HAVE_SETPAYLOAD. * modules/setpayload: New file. * doc/posix-functions/setpayload.texi: Mention the new module. --- ChangeLog | 14 +++++++ doc/posix-functions/setpayload.texi | 8 ++-- lib/math.in.h | 16 ++++++++ lib/setpayload.c | 59 +++++++++++++++++++++++++++ m4/math_h.m4 | 8 +++- m4/setpayload.m4 | 63 +++++++++++++++++++++++++++++ modules/math | 2 + modules/setpayload | 36 +++++++++++++++++ 8 files changed, 200 insertions(+), 6 deletions(-) create mode 100644 lib/setpayload.c create mode 100644 m4/setpayload.m4 create mode 100644 modules/setpayload diff --git a/ChangeLog b/ChangeLog index 8418f71093..4f80fc03e4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2024-04-16 Bruno Haible + + setpayload: New module. + * lib/math.in.h (setpayload): New declaration. + * lib/setpayload.c: New file. + * m4/setpayload.m4: New file. + * m4/math_h.m4 (gl_MATH_H): Test whether setpayload is declared. + (gl_MATH_H_REQUIRE_DEFAULTS): Initialize GNULIB_SETPAYLOAD. + (gl_MATH_H_DEFAULTS): Initialize HAVE_SETPAYLOAD. + * modules/math (Makefile.am): Substitute GNULIB_SETPAYLOAD, + HAVE_SETPAYLOAD. + * modules/setpayload: New file. + * doc/posix-functions/setpayload.texi: Mention the new module. + 2024-04-15 Collin Funk gnulib-tool.py: Optimize directory creation. diff --git a/doc/posix-functions/setpayload.texi b/doc/posix-functions/setpayload.texi index e41a059cfa..26109fbd49 100644 --- a/doc/posix-functions/setpayload.texi +++ b/doc/posix-functions/setpayload.texi @@ -10,15 +10,15 @@ Documentation:@* @url{https://www.gnu.org/software/libc/manual/html_node/FP-Bit-Twiddling.html}. @end ifnotinfo -Gnulib module: --- +Gnulib module: setpayload 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. @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/math.in.h b/lib/math.in.h index 72a61d7044..3a2fb5cde7 100644 --- a/lib/math.in.h +++ b/lib/math.in.h @@ -2774,6 +2774,21 @@ _GL_WARN_REAL_FLOATING_DECL (signbit); #endif +#if @GNULIB_SETPAYLOAD@ +# if !@HAVE_SETPAYLOAD@ +_GL_FUNCDECL_SYS (setpayload, int, (double *, double)); +# endif +_GL_CXXALIAS_SYS (setpayload, int, (double *, double)); +_GL_CXXALIASWARN (setpayload); +#elif defined GNULIB_POSIXCHECK +# undef setpayload +# if HAVE_RAW_DECL_SETPAYLOAD +_GL_WARN_ON_USE (setpayload, "setpayload is unportable - " + "use gnulib module setpayload for portability"); +# endif +#endif + + #if @GNULIB_TOTALORDERF@ # if @REPLACE_TOTALORDERF@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) @@ -2849,6 +2864,7 @@ _GL_WARN_ON_USE (totalorderl, "totalorderl is unportable - " # endif #endif + _GL_INLINE_HEADER_END #endif /* _@GUARD_PREFIX@_MATH_H */ diff --git a/lib/setpayload.c b/lib/setpayload.c new file mode 100644 index 0000000000..fa5c7ad866 --- /dev/null +++ b/lib/setpayload.c @@ -0,0 +1,59 @@ +/* Construct a quiet NaN 'double' with a given payload. + 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 . */ + +/* Written by Bruno Haible. */ + +#include + +/* Specification. */ +#include + +#include +#include + +#include "signed-nan.h" + +int +setpayload (double *result, double payload) +{ +#if DBL_MANT_DIG == 53 + if ( +# if defined __hppa || defined __mips__ || defined __sh__ + /* A zero payload is not allowed, because that would denote Infinity. + Cf. snan.h. */ + payload > 0.0 +# else + payload >= 0.0 +# endif + && payload < 2251799813685248.0 /* (double) (1ULL << (DBL_MANT_DIG - 2)) */ + && payload == (double) (int64_t) payload) + { + union { uint64_t i; double f; } x; + x.f = positive_NaNd (); + x.i = (x.i & ~(((uint64_t) 1 << (DBL_MANT_DIG - 2)) - 1)) + | (int64_t) payload; + *result = x.f; + return 0; + } + else + { + *result = 0.0; + return -1; + } +#else +# error "Please port gnulib setpayload.c to your platform!" +#endif +} diff --git a/m4/math_h.m4 b/m4/math_h.m4 index e164c137e4..2fa5d9fb28 100644 --- a/m4/math_h.m4 +++ b/m4/math_h.m4 @@ -1,5 +1,5 @@ # math_h.m4 -# serial 126 +# serial 127 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, @@ -50,7 +50,9 @@ AC_DEFUN_ONCE([gl_MATH_H], logb logbf logbl modf modff modfl powf remainder remainderf remainderl - rint rintf rintl round roundf roundl sinf sinl sinhf sqrtf sqrtl + rint rintf rintl round roundf roundl + setpayload + sinf sinl sinhf sqrtf sqrtl tanf tanl tanhf totalorder totalorderf totalorderl trunc truncf truncl]) ]) @@ -157,6 +159,7 @@ AC_DEFUN([gl_MATH_H_REQUIRE_DEFAULTS], gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ROUND]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ROUNDF]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ROUNDL]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SETPAYLOAD]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SIGNBIT]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SINF]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SINL]) @@ -239,6 +242,7 @@ AC_DEFUN([gl_MATH_H_DEFAULTS], HAVE_REMAINDERF=1; AC_SUBST([HAVE_REMAINDERF]) HAVE_RINT=1; AC_SUBST([HAVE_RINT]) HAVE_RINTL=1; AC_SUBST([HAVE_RINTL]) + HAVE_SETPAYLOAD=1; AC_SUBST([HAVE_SETPAYLOAD]) HAVE_SINF=1; AC_SUBST([HAVE_SINF]) HAVE_SINL=1; AC_SUBST([HAVE_SINL]) HAVE_SINHF=1; AC_SUBST([HAVE_SINHF]) diff --git a/m4/setpayload.m4 b/m4/setpayload.m4 new file mode 100644 index 0000000000..5238dd0de5 --- /dev/null +++ b/m4/setpayload.m4 @@ -0,0 +1,63 @@ +# setpayload.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_SETPAYLOADF], +[ + AC_REQUIRE([gl_MATH_H_DEFAULTS]) + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + + gl_MATHFUNC([setpayloadf], [int], [(float *, float)]) + if test $gl_cv_func_setpayloadf_no_libm != yes \ + && test $gl_cv_func_setpayloadf_in_libm != yes; then + HAVE_SETPAYLOADF=0 + fi + if test $HAVE_SETPAYLOADF = 0; then + SETPAYLOADF_LIBM= + fi + AC_SUBST([SETPAYLOADF_LIBM]) +]) + +AC_DEFUN_ONCE([gl_FUNC_SETPAYLOAD], +[ + AC_REQUIRE([gl_MATH_H_DEFAULTS]) + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + + gl_MATHFUNC([setpayload], [int], [(double *, double)]) + if test $gl_cv_func_setpayload_no_libm != yes \ + && test $gl_cv_func_setpayload_in_libm != yes; then + HAVE_SETPAYLOAD=0 + fi + if test $HAVE_SETPAYLOAD = 0; then + SETPAYLOAD_LIBM= + fi + AC_SUBST([SETPAYLOAD_LIBM]) +]) + +AC_DEFUN([gl_FUNC_SETPAYLOADL], +[ + AC_REQUIRE([gl_MATH_H_DEFAULTS]) + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + AC_REQUIRE([gl_LONG_DOUBLE_VS_DOUBLE]) + + gl_MATHFUNC([setpayloadl], [int], [(long double *, long double)]) + if test $gl_cv_func_setpayloadl_no_libm != yes \ + && test $gl_cv_func_setpayloadl_in_libm != yes; then + HAVE_SETPAYLOADL=0 + fi + if test $HAVE_SETPAYLOADL = 0; then + dnl Find libraries needed to link lib/setpayloadl.c. + if test $HAVE_SAME_LONG_DOUBLE_AS_DOUBLE = 1; then + AC_REQUIRE([gl_FUNC_SETPAYLOAD]) + SETPAYLOADL_LIBM="$SETPAYLOAD_LIBM" + else + SETPAYLOADL_LIBM= + fi + dnl Prerequisite of lib/setpayloadl.c. + gl_LONG_DOUBLE_EXPONENT_LOCATION + fi + AC_SUBST([SETPAYLOADL_LIBM]) +]) diff --git a/modules/math b/modules/math index f816d64cd2..8f61f70ae1 100644 --- a/modules/math +++ b/modules/math @@ -120,6 +120,7 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( -e 's/@''GNULIB_ROUND''@/$(GNULIB_ROUND)/g' \ -e 's/@''GNULIB_ROUNDF''@/$(GNULIB_ROUNDF)/g' \ -e 's/@''GNULIB_ROUNDL''@/$(GNULIB_ROUNDL)/g' \ + -e 's/@''GNULIB_SETPAYLOAD''@/$(GNULIB_SETPAYLOAD)/g' \ -e 's/@''GNULIB_SIGNBIT''@/$(GNULIB_SIGNBIT)/g' \ -e 's/@''GNULIB_SINF''@/$(GNULIB_SINF)/g' \ -e 's/@''GNULIB_SINL''@/$(GNULIB_SINL)/g' \ @@ -195,6 +196,7 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( -e 's|@''HAVE_REMAINDERF''@|$(HAVE_REMAINDERF)|g' \ -e 's|@''HAVE_RINT''@|$(HAVE_RINT)|g' \ -e 's|@''HAVE_RINTL''@|$(HAVE_RINTL)|g' \ + -e 's|@''HAVE_SETPAYLOAD''@|$(HAVE_SETPAYLOAD)|g' \ -e 's|@''HAVE_SINF''@|$(HAVE_SINF)|g' \ -e 's|@''HAVE_SINL''@|$(HAVE_SINL)|g' \ -e 's|@''HAVE_SINHF''@|$(HAVE_SINHF)|g' \ diff --git a/modules/setpayload b/modules/setpayload new file mode 100644 index 0000000000..677335a3ae --- /dev/null +++ b/modules/setpayload @@ -0,0 +1,36 @@ +Description: +setpayload function: construct a quiet NaN with a given payload + +Files: +lib/setpayload.c +m4/mathfunc.m4 +m4/setpayload.m4 + +Depends-on: +math +extensions +float [test $HAVE_SETPAYLOAD = 0] +stdint [test $HAVE_SETPAYLOAD = 0] +signed-nan [test $HAVE_SETPAYLOAD = 0] + +configure.ac: +gl_FUNC_SETPAYLOAD +gl_CONDITIONAL([GL_COND_OBJ_SETPAYLOAD], [test $HAVE_SETPAYLOAD = 0]) +gl_MATH_MODULE_INDICATOR([setpayload]) + +Makefile.am: +if GL_COND_OBJ_SETPAYLOAD +lib_SOURCES += setpayload.c +endif + +Include: + + +Link: +$(SETPAYLOAD_LIBM) + +License: +LGPL + +Maintainer: +all -- 2.39.5