From eaa0ca659f7548c3e7f38231bc4ee7c34770d8f9 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Tue, 16 Apr 2024 14:39:16 +0200 Subject: [PATCH] setpayloadf: New module. * lib/math.in.h (setpayloadf): New declaration. * lib/setpayloadf.c: New file. * m4/math_h.m4 (gl_MATH_H): Test whether setpayloadf is declared. (gl_MATH_H_REQUIRE_DEFAULTS): Initialize GNULIB_SETPAYLOADF. (gl_MATH_H_DEFAULTS): Initialize HAVE_SETPAYLOADF. * modules/math (Makefile.am): Substitute GNULIB_SETPAYLOADF, HAVE_SETPAYLOADF. * modules/setpayloadf: New file. * doc/posix-functions/setpayloadf.texi: Mention the new module. --- ChangeLog | 13 ++++++ doc/posix-functions/setpayloadf.texi | 8 ++-- lib/math.in.h | 14 +++++++ lib/setpayloadf.c | 59 ++++++++++++++++++++++++++++ m4/math_h.m4 | 6 ++- modules/math | 2 + modules/setpayloadf | 36 +++++++++++++++++ 7 files changed, 132 insertions(+), 6 deletions(-) create mode 100644 lib/setpayloadf.c create mode 100644 modules/setpayloadf diff --git a/ChangeLog b/ChangeLog index 97d8a3d64f..9640eb8ef1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2024-04-16 Bruno Haible + + setpayloadf: New module. + * lib/math.in.h (setpayloadf): New declaration. + * lib/setpayloadf.c: New file. + * m4/math_h.m4 (gl_MATH_H): Test whether setpayloadf is declared. + (gl_MATH_H_REQUIRE_DEFAULTS): Initialize GNULIB_SETPAYLOADF. + (gl_MATH_H_DEFAULTS): Initialize HAVE_SETPAYLOADF. + * modules/math (Makefile.am): Substitute GNULIB_SETPAYLOADF, + HAVE_SETPAYLOADF. + * modules/setpayloadf: New file. + * doc/posix-functions/setpayloadf.texi: Mention the new module. + 2024-04-16 Bruno Haible setpayload: Add tests. diff --git a/doc/posix-functions/setpayloadf.texi b/doc/posix-functions/setpayloadf.texi index c225c1b1f4..05616f9d41 100644 --- a/doc/posix-functions/setpayloadf.texi +++ b/doc/posix-functions/setpayloadf.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: setpayloadf 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 3a2fb5cde7..1fd41c2722 100644 --- a/lib/math.in.h +++ b/lib/math.in.h @@ -2774,6 +2774,20 @@ _GL_WARN_REAL_FLOATING_DECL (signbit); #endif +#if @GNULIB_SETPAYLOADF@ +# if !@HAVE_SETPAYLOADF@ +_GL_FUNCDECL_SYS (setpayloadf, int, (float *, float)); +# endif +_GL_CXXALIAS_SYS (setpayloadf, int, (float *, float)); +_GL_CXXALIASWARN (setpayloadf); +#elif defined GNULIB_POSIXCHECK +# undef setpayloadf +# if HAVE_RAW_DECL_SETPAYLOADF +_GL_WARN_ON_USE (setpayloadf, "setpayloadf is unportable - " + "use gnulib module setpayloadf for portability"); +# endif +#endif + #if @GNULIB_SETPAYLOAD@ # if !@HAVE_SETPAYLOAD@ _GL_FUNCDECL_SYS (setpayload, int, (double *, double)); diff --git a/lib/setpayloadf.c b/lib/setpayloadf.c new file mode 100644 index 0000000000..1f02bc4593 --- /dev/null +++ b/lib/setpayloadf.c @@ -0,0 +1,59 @@ +/* Construct a quiet NaN 'float' 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 +setpayloadf (float *result, float payload) +{ +#if FLT_MANT_DIG == 24 + if ( +# if defined __hppa || defined __mips__ || defined __sh__ + /* A zero payload is not allowed, because that would denote Infinity. + Cf. snan.h. */ + payload > 0.0f +# else + payload >= 0.0f +# endif + && payload < 4194304.0f /* (float) (1U << (FLT_MANT_DIG - 2)) */ + && payload == (float) (int32_t) payload) + { + union { uint32_t i; float f; } x; + x.f = positive_NaNf (); + x.i = (x.i & ~(((uint32_t) 1 << (FLT_MANT_DIG - 2)) - 1)) + | (int32_t) payload; + *result = x.f; + return 0; + } + else + { + *result = 0.0f; + return -1; + } +#else +# error "Please port gnulib setpayloadf.c to your platform!" +#endif +} diff --git a/m4/math_h.m4 b/m4/math_h.m4 index 2fa5d9fb28..ee32128089 100644 --- a/m4/math_h.m4 +++ b/m4/math_h.m4 @@ -1,5 +1,5 @@ # math_h.m4 -# serial 127 +# serial 128 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, @@ -51,7 +51,7 @@ AC_DEFUN_ONCE([gl_MATH_H], modf modff modfl powf remainder remainderf remainderl rint rintf rintl round roundf roundl - setpayload + setpayload setpayloadf sinf sinl sinhf sqrtf sqrtl tanf tanl tanhf totalorder totalorderf totalorderl trunc truncf truncl]) ]) @@ -160,6 +160,7 @@ AC_DEFUN([gl_MATH_H_REQUIRE_DEFAULTS], 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_SETPAYLOADF]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SIGNBIT]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SINF]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SINL]) @@ -243,6 +244,7 @@ AC_DEFUN([gl_MATH_H_DEFAULTS], HAVE_RINT=1; AC_SUBST([HAVE_RINT]) HAVE_RINTL=1; AC_SUBST([HAVE_RINTL]) HAVE_SETPAYLOAD=1; AC_SUBST([HAVE_SETPAYLOAD]) + HAVE_SETPAYLOADF=1; AC_SUBST([HAVE_SETPAYLOADF]) HAVE_SINF=1; AC_SUBST([HAVE_SINF]) HAVE_SINL=1; AC_SUBST([HAVE_SINL]) HAVE_SINHF=1; AC_SUBST([HAVE_SINHF]) diff --git a/modules/math b/modules/math index 8f61f70ae1..f0233b94c4 100644 --- a/modules/math +++ b/modules/math @@ -121,6 +121,7 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( -e 's/@''GNULIB_ROUNDF''@/$(GNULIB_ROUNDF)/g' \ -e 's/@''GNULIB_ROUNDL''@/$(GNULIB_ROUNDL)/g' \ -e 's/@''GNULIB_SETPAYLOAD''@/$(GNULIB_SETPAYLOAD)/g' \ + -e 's/@''GNULIB_SETPAYLOADF''@/$(GNULIB_SETPAYLOADF)/g' \ -e 's/@''GNULIB_SIGNBIT''@/$(GNULIB_SIGNBIT)/g' \ -e 's/@''GNULIB_SINF''@/$(GNULIB_SINF)/g' \ -e 's/@''GNULIB_SINL''@/$(GNULIB_SINL)/g' \ @@ -197,6 +198,7 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( -e 's|@''HAVE_RINT''@|$(HAVE_RINT)|g' \ -e 's|@''HAVE_RINTL''@|$(HAVE_RINTL)|g' \ -e 's|@''HAVE_SETPAYLOAD''@|$(HAVE_SETPAYLOAD)|g' \ + -e 's|@''HAVE_SETPAYLOADF''@|$(HAVE_SETPAYLOADF)|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/setpayloadf b/modules/setpayloadf new file mode 100644 index 0000000000..05856e62da --- /dev/null +++ b/modules/setpayloadf @@ -0,0 +1,36 @@ +Description: +setpayloadf function: construct a quiet NaN with a given payload + +Files: +lib/setpayloadf.c +m4/mathfunc.m4 +m4/setpayload.m4 + +Depends-on: +math +extensions +float [test $HAVE_SETPAYLOADF = 0] +stdint [test $HAVE_SETPAYLOADF = 0] +signed-nan [test $HAVE_SETPAYLOADF = 0] + +configure.ac: +gl_FUNC_SETPAYLOADF +gl_CONDITIONAL([GL_COND_OBJ_SETPAYLOADF], [test $HAVE_SETPAYLOADF = 0]) +gl_MATH_MODULE_INDICATOR([setpayloadf]) + +Makefile.am: +if GL_COND_OBJ_SETPAYLOADF +lib_SOURCES += setpayloadf.c +endif + +Include: + + +Link: +$(SETPAYLOADF_LIBM) + +License: +LGPL + +Maintainer: +all -- 2.39.5