# HG changeset patch # User Bruno Haible # Date 1333480406 -7200 # Node ID 4f4f1518fbab463c8836ce97f910e357c0ade842 # Parent f3fe07944aae8758c20775fe496465d3bae3d299 New module 'ilogbf'. * lib/math.in.h (ilogbf): New declaration. * lib/ilogbf.c: New file. * m4/ilogbf.m4: New file. * m4/math_h.m4 (gl_MATH_H): Test whether ilogbf is declared. (gl_MATH_H_DEFAULTS): Initialize GNULIB_ILOGBF, HAVE_ILOGBF, REPLACE_ILOGBF. * modules/math (Makefile.am): Substitute GNULIB_ILOGBF, HAVE_ILOGBF, REPLACE_ILOGBF. * modules/ilogbf: New file. * tests/test-math-c++.cc: Check the declaration of ilogbf. * doc/posix-functions/ilogbf.texi: Mention the new module. diff --git a/ChangeLog b/ChangeLog --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2012-04-03 Bruno Haible + + New module 'ilogbf'. + * lib/math.in.h (ilogbf): New declaration. + * lib/ilogbf.c: New file. + * m4/ilogbf.m4: New file. + * m4/math_h.m4 (gl_MATH_H): Test whether ilogbf is declared. + (gl_MATH_H_DEFAULTS): Initialize GNULIB_ILOGBF, HAVE_ILOGBF, + REPLACE_ILOGBF. + * modules/math (Makefile.am): Substitute GNULIB_ILOGBF, HAVE_ILOGBF, + REPLACE_ILOGBF. + * modules/ilogbf: New file. + * tests/test-math-c++.cc: Check the declaration of ilogbf. + * doc/posix-functions/ilogbf.texi: Mention the new module. + 2012-04-03 Bruno Haible Tests for module 'ilogb'. diff --git a/doc/posix-functions/ilogbf.texi b/doc/posix-functions/ilogbf.texi --- a/doc/posix-functions/ilogbf.texi +++ b/doc/posix-functions/ilogbf.texi @@ -4,15 +4,21 @@ POSIX specification:@* @url{http://www.opengroup.org/onlinepubs/9699919799/functions/ilogbf.html} -Gnulib module: --- +Gnulib module: ilogbf Portability problems fixed by Gnulib: @itemize +@item +This function is missing on some platforms: +Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 9, MSVC 9. +@item +This function returns a wrong result for a zero argument on some platforms: +OpenBSD 4.9. +@item +This function returns a wrong result for an infinite argument on some platforms: +NetBSD 5.1, OpenBSD 4.9. @end itemize Portability problems not fixed by Gnulib: @itemize -@item -This function is missing on some platforms: -Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 9, MSVC 9. @end itemize diff --git a/lib/ilogbf.c b/lib/ilogbf.c new file mode 100644 --- /dev/null +++ b/lib/ilogbf.c @@ -0,0 +1,23 @@ +/* Floating-point exponent. + Copyright (C) 2012 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 . */ + +#include + +/* Specification. */ +#include + +#define USE_FLOAT +#include "ilogb.c" diff --git a/lib/math.in.h b/lib/math.in.h --- a/lib/math.in.h +++ b/lib/math.in.h @@ -1087,6 +1087,29 @@ #endif +#if @GNULIB_ILOGBF@ +# if @REPLACE_ILOGBF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef ilogbf +# define ilogbf rpl_ilogbf +# endif +_GL_FUNCDECL_RPL (ilogbf, int, (float x)); +_GL_CXXALIAS_RPL (ilogbf, int, (float x)); +# else +# if !@HAVE_ILOGBF@ +_GL_FUNCDECL_SYS (ilogbf, int, (float x)); +# endif +_GL_CXXALIAS_SYS (ilogbf, int, (float x)); +# endif +_GL_CXXALIASWARN (ilogbf); +#elif defined GNULIB_POSIXCHECK +# undef ilogbf +# if HAVE_RAW_DECL_ILOGBF +_GL_WARN_ON_USE (ilogbf, "ilogbf is unportable - " + "use gnulib module ilogbf for portability"); +# endif +#endif + #if @GNULIB_ILOGB@ # if @REPLACE_ILOGB@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) diff --git a/m4/ilogbf.m4 b/m4/ilogbf.m4 new file mode 100644 --- /dev/null +++ b/m4/ilogbf.m4 @@ -0,0 +1,107 @@ +# ilogbf.m4 serial 1 +dnl Copyright (C) 2010-2012 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_ILOGBF], +[ + AC_REQUIRE([gl_MATH_H_DEFAULTS]) + + dnl Persuade glibc to declare ilogbf(). + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + + dnl Determine ILOGBF_LIBM. + gl_MATHFUNC([ilogbf], [int], [(float)]) + if test $gl_cv_func_ilogbf_no_libm = yes \ + || test $gl_cv_func_ilogbf_in_libm = yes; then + save_LIBS="$LIBS" + LIBS="$LIBS $ILOGBF_LIBM" + gl_FUNC_ILOGBF_WORKS + LIBS="$save_LIBS" + case "$gl_cv_func_ilogbf_works" in + *yes) ;; + *) REPLACE_ILOGBF=1 ;; + esac + else + HAVE_ILOGBF=0 + fi + if test $HAVE_ILOGBF = 0 || test $REPLACE_ILOGBF = 1; then + dnl Find libraries needed to link lib/ilogbf.c. + AC_REQUIRE([gl_FUNC_FREXPF]) + AC_REQUIRE([gl_FUNC_ISNANF]) + ILOGBF_LIBM= + dnl Append $FREXPF_LIBM to ILOGBF_LIBM, avoiding gratuitous duplicates. + case " $ILOGBF_LIBM " in + *" $FREXPF_LIBM "*) ;; + *) ILOGBF_LIBM="$ILOGBF_LIBM $FREXPF_LIBM" ;; + esac + dnl Append $ISNANF_LIBM to ILOGBF_LIBM, avoiding gratuitous duplicates. + case " $ILOGBF_LIBM " in + *" $ISNANF_LIBM "*) ;; + *) ILOGBF_LIBM="$ILOGBF_LIBM $ISNANF_LIBM" ;; + esac + fi + AC_SUBST([ILOGBF_LIBM]) +]) + +dnl Test whether ilogbf() works. +dnl On OpenBSD 4.9, ilogbf(0.0) is wrong. +dnl On NetBSD 5.1, OpenBSD 4.9, ilogbf(Infinity) is wrong. +AC_DEFUN([gl_FUNC_ILOGBF_WORKS], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether ilogbf works], [gl_cv_func_ilogbf_works], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +/* Provide FP_ILOGB0, FP_ILOGBNAN, like in math.in.h. */ +#if !(defined FP_ILOGB0 && defined FP_ILOGBNAN) +# if defined __NetBSD__ || defined __sgi + /* NetBSD, IRIX 6.5: match what ilogbf() does */ +# define FP_ILOGB0 INT_MIN +# define FP_ILOGBNAN INT_MIN +# elif defined _AIX + /* AIX 5.1: match what ilogbf() does in AIX >= 5.2 */ +# define FP_ILOGB0 INT_MIN +# define FP_ILOGBNAN INT_MAX +# elif defined __sun + /* Solaris 9: match what ilogbf() does */ +# define FP_ILOGB0 (- INT_MAX) +# define FP_ILOGBNAN INT_MAX +# endif +#endif +volatile float x; +static float zero; +static int dummy (float x) { return 0; } +int main (int argc, char *argv[]) +{ + int (*my_ilogbf) (float) = argc ? ilogbf : dummy; + int result = 0; + /* This test fails on OpenBSD 4.9. */ + { + x = 0.0f; + if (my_ilogbf (x) != FP_ILOGB0) + result |= 1; + } + /* This test fails on NetBSD 5.1, OpenBSD 4.9. */ + { + x = 1.0f / zero; + if (my_ilogbf (x) != INT_MAX) + result |= 2; + } + return result; +} +]])], + [gl_cv_func_ilogbf_works=yes], + [gl_cv_func_ilogbf_works=no], + [case "$host_os" in + openbsd* | netbsd*) gl_cv_func_ilogbf_works="guessing no";; + *) gl_cv_func_ilogbf_works="guessing yes";; + esac + ]) + ]) +]) diff --git a/m4/math_h.m4 b/m4/math_h.m4 --- a/m4/math_h.m4 +++ b/m4/math_h.m4 @@ -1,4 +1,4 @@ -# math_h.m4 serial 111 +# math_h.m4 serial 112 dnl Copyright (C) 2007-2012 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 @@ expf expl exp2 exp2f exp2l expm1 expm1f expm1l fabsf fabsl floorf floorl fma fmaf fmal fmod fmodf fmodl frexpf frexpl hypotf hypotl - ilogb + ilogb ilogbf ldexpf ldexpl log logf logl log10 log10f log10l log1p log1pf log1pl log2 log2f log2l logb logbf logbl @@ -110,6 +110,7 @@ GNULIB_HYPOTF=0; AC_SUBST([GNULIB_HYPOTF]) GNULIB_HYPOTL=0; AC_SUBST([GNULIB_HYPOTL]) GNULIB_ILOGB=0; AC_SUBST([GNULIB_ILOGB]) + GNULIB_ILOGBF=0; AC_SUBST([GNULIB_ILOGBF]) GNULIB_ISFINITE=0; AC_SUBST([GNULIB_ISFINITE]) GNULIB_ISINF=0; AC_SUBST([GNULIB_ISINF]) GNULIB_ISNAN=0; AC_SUBST([GNULIB_ISNAN]) @@ -189,6 +190,7 @@ HAVE_HYPOTF=1; AC_SUBST([HAVE_HYPOTF]) HAVE_HYPOTL=1; AC_SUBST([HAVE_HYPOTL]) HAVE_ILOGB=1; AC_SUBST([HAVE_ILOGB]) + HAVE_ILOGBF=1; AC_SUBST([HAVE_ILOGBF]) HAVE_ISNANF=1; AC_SUBST([HAVE_ISNANF]) HAVE_ISNAND=1; AC_SUBST([HAVE_ISNAND]) HAVE_ISNANL=1; AC_SUBST([HAVE_ISNANL]) @@ -280,6 +282,7 @@ REPLACE_HYPOTF=0; AC_SUBST([REPLACE_HYPOTF]) REPLACE_HYPOTL=0; AC_SUBST([REPLACE_HYPOTL]) REPLACE_ILOGB=0; AC_SUBST([REPLACE_ILOGB]) + REPLACE_ILOGBF=0; AC_SUBST([REPLACE_ILOGBF]) REPLACE_ISFINITE=0; AC_SUBST([REPLACE_ISFINITE]) REPLACE_ISINF=0; AC_SUBST([REPLACE_ISINF]) REPLACE_ISNAN=0; AC_SUBST([REPLACE_ISNAN]) diff --git a/modules/ilogbf b/modules/ilogbf new file mode 100644 --- /dev/null +++ b/modules/ilogbf @@ -0,0 +1,36 @@ +Description: +ilogbf() function: get exponent as integer. + +Files: +lib/ilogbf.c +lib/ilogb.c +m4/ilogbf.m4 +m4/mathfunc.m4 + +Depends-on: +math +extensions +isfinite [test $HAVE_ILOGBF = 0 || test $REPLACE_ILOGBF = 1] +frexpf [test $HAVE_ILOGBF = 0 || test $REPLACE_ILOGBF = 1] +isnanf [test $HAVE_ILOGBF = 0 || test $REPLACE_ILOGBF = 1] + +configure.ac: +gl_FUNC_ILOGBF +if test $HAVE_ILOGBF = 0 || test $REPLACE_ILOGBF = 1; then + AC_LIBOBJ([ilogbf]) +fi +gl_MATH_MODULE_INDICATOR([ilogbf]) + +Makefile.am: + +Include: + + +Link: +$(ILOGBF_LIBM) + +License: +LGPL + +Maintainer: +Bruno Haible diff --git a/modules/math b/modules/math --- a/modules/math +++ b/modules/math @@ -73,6 +73,7 @@ -e 's/@''GNULIB_HYPOTF''@/$(GNULIB_HYPOTF)/g' \ -e 's/@''GNULIB_HYPOTL''@/$(GNULIB_HYPOTL)/g' \ -e 's/@''GNULIB_ILOGB''@/$(GNULIB_ILOGB)/g' \ + -e 's/@''GNULIB_ILOGBF''@/$(GNULIB_ILOGBF)/g' \ -e 's/@''GNULIB_ISFINITE''@/$(GNULIB_ISFINITE)/g' \ -e 's/@''GNULIB_ISINF''@/$(GNULIB_ISINF)/g' \ -e 's/@''GNULIB_ISNAN''@/$(GNULIB_ISNAN)/g' \ @@ -152,6 +153,7 @@ -e 's|@''HAVE_HYPOTF''@|$(HAVE_HYPOTF)|g' \ -e 's|@''HAVE_HYPOTL''@|$(HAVE_HYPOTL)|g' \ -e 's|@''HAVE_ILOGB''@|$(HAVE_ILOGB)|g' \ + -e 's|@''HAVE_ILOGBF''@|$(HAVE_ILOGBF)|g' \ -e 's|@''HAVE_ISNANF''@|$(HAVE_ISNANF)|g' \ -e 's|@''HAVE_ISNAND''@|$(HAVE_ISNAND)|g' \ -e 's|@''HAVE_ISNANL''@|$(HAVE_ISNANL)|g' \ @@ -244,6 +246,7 @@ -e 's|@''REPLACE_HYPOTF''@|$(REPLACE_HYPOTF)|g' \ -e 's|@''REPLACE_HYPOTL''@|$(REPLACE_HYPOTL)|g' \ -e 's|@''REPLACE_ILOGB''@|$(REPLACE_ILOGB)|g' \ + -e 's|@''REPLACE_ILOGBF''@|$(REPLACE_ILOGBF)|g' \ -e 's|@''REPLACE_ISFINITE''@|$(REPLACE_ISFINITE)|g' \ -e 's|@''REPLACE_ISINF''@|$(REPLACE_ISINF)|g' \ -e 's|@''REPLACE_ISNAN''@|$(REPLACE_ISNAN)|g' \ diff --git a/tests/test-math-c++.cc b/tests/test-math-c++.cc --- a/tests/test-math-c++.cc +++ b/tests/test-math-c++.cc @@ -194,6 +194,9 @@ (long double, long double)); #endif +#if GNULIB_TEST_ILOGBF +SIGNATURE_CHECK (GNULIB_NAMESPACE::ilogbf, int, (float)); +#endif #if GNULIB_TEST_ILOGB SIGNATURE_CHECK (GNULIB_NAMESPACE::ilogb, int, (double)); #endif