diff options
-rw-r--r-- | ChangeLog | 15 | ||||
-rw-r--r-- | doc/posix-functions/logbf.texi | 11 | ||||
-rw-r--r-- | lib/logbf.c | 23 | ||||
-rw-r--r-- | lib/math.in.h | 23 | ||||
-rw-r--r-- | m4/logbf.m4 | 81 | ||||
-rw-r--r-- | m4/math_h.m4 | 7 | ||||
-rw-r--r-- | modules/logbf | 36 | ||||
-rw-r--r-- | modules/math | 3 | ||||
-rw-r--r-- | tests/test-math-c++.cc | 3 |
9 files changed, 196 insertions, 6 deletions
@@ -1,5 +1,20 @@ 2012-04-02 Bruno Haible <bruno@clisp.org> + New module 'logbf'. + * lib/math.in.h (logbf): New declaration. + * lib/logbf.c: New file. + * m4/logbf.m4: New file. + * m4/math_h.m4 (gl_MATH_H): Test whether logbf is declared. + (gl_MATH_H_DEFAULTS): Initialize GNULIB_LOGBF, HAVE_LOGBF, + REPLACE_LOGBF. + * modules/math (Makefile.am): Substitute GNULIB_LOGBF, HAVE_LOGBF, + REPLACE_LOGBF. + * modules/logbf: New file. + * tests/test-math-c++.cc: Check the declaration of logbf. + * doc/posix-functions/logbf.texi: Mention the new module. + +2012-04-02 Bruno Haible <bruno@clisp.org> + logb tests: More tests. * tests/test-logb.h: New file, based on tests/test-logb.c and tests/test-frexp.h. diff --git a/doc/posix-functions/logbf.texi b/doc/posix-functions/logbf.texi index ec943620bf..670d689fb4 100644 --- a/doc/posix-functions/logbf.texi +++ b/doc/posix-functions/logbf.texi @@ -4,15 +4,18 @@ POSIX specification:@* @url{http://www.opengroup.org/onlinepubs/9699919799/functions/logbf.html} -Gnulib module: --- +Gnulib module: logbf 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 produces wrong results for subnormal numbers on some platforms: +glibc 2.11/ppc, glibc 2.7/sparc, glibc 2.7/hppa, Solaris 11 2011-11. @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/logbf.c b/lib/logbf.c new file mode 100644 index 0000000000..910d652d61 --- /dev/null +++ b/lib/logbf.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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <math.h> + +#define USE_FLOAT +#include "logb.c" diff --git a/lib/math.in.h b/lib/math.in.h index 40983a9640..247c64417c 100644 --- a/lib/math.in.h +++ b/lib/math.in.h @@ -1388,6 +1388,29 @@ _GL_WARN_ON_USE (log2l, "log2l is unportable - " #endif +#if @GNULIB_LOGBF@ +# if @REPLACE_LOGBF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef logbf +# define logbf rpl_logbf +# endif +_GL_FUNCDECL_RPL (logbf, float, (float x)); +_GL_CXXALIAS_RPL (logbf, float, (float x)); +# else +# if !@HAVE_LOGBF@ +_GL_FUNCDECL_SYS (logbf, float, (float x)); +# endif +_GL_CXXALIAS_SYS (logbf, float, (float x)); +# endif +_GL_CXXALIASWARN (logbf); +#elif defined GNULIB_POSIXCHECK +# undef logbf +# if HAVE_RAW_DECL_LOGBF +_GL_WARN_ON_USE (logbf, "logbf is unportable - " + "use gnulib module logbf for portability"); +# endif +#endif + #if @GNULIB_LOGB@ # if @REPLACE_LOGB@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) diff --git a/m4/logbf.m4 b/m4/logbf.m4 new file mode 100644 index 0000000000..5937c96a23 --- /dev/null +++ b/m4/logbf.m4 @@ -0,0 +1,81 @@ +# logbf.m4 serial 1 +dnl Copyright (C) 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_LOGBF], +[ + AC_REQUIRE([gl_MATH_H_DEFAULTS]) + + dnl Persuade glibc <math.h> to declare logbf(). + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + + dnl Determine LOGBF_LIBM. + gl_MATHFUNC([logbf], [float], [(float)]) + if test $gl_cv_func_logbf_no_libm = yes \ + || test $gl_cv_func_logbf_in_libm = yes; then + save_LIBS="$LIBS" + LIBS="$LIBS $LOGBF_LIBM" + gl_FUNC_LOGBF_WORKS + LIBS="$save_LIBS" + case "$gl_cv_func_logbf_works" in + *yes) ;; + *) REPLACE_LOGBF=1 ;; + esac + else + HAVE_LOGBF=0 + fi + if test $HAVE_LOGBF = 0 || test $REPLACE_LOGBF = 1; then + dnl Find libraries needed to link lib/logbf.c. + AC_REQUIRE([gl_FUNC_FREXPF]) + AC_REQUIRE([gl_FUNC_ISNANF]) + LOGBF_LIBM= + dnl Append $FREXPF_LIBM to LOGBF_LIBM, avoiding gratuitous duplicates. + case " $LOGBF_LIBM " in + *" $FREXPF_LIBM "*) ;; + *) LOGBF_LIBM="$LOGBF_LIBM $FREXPF_LIBM" ;; + esac + dnl Append $ISNANF_LIBM to LOGBF_LIBM, avoiding gratuitous duplicates. + case " $LOGBF_LIBM " in + *" $ISNANF_LIBM "*) ;; + *) LOGBF_LIBM="$LOGBF_LIBM $ISNANF_LIBM" ;; + esac + fi + AC_SUBST([LOGBF_LIBM]) +]) + +dnl Test whether logbf() works. +dnl On glibc 2.11/ppc, glibc 2.7/sparc, glibc 2.7/hppa, Solaris 10/SPARC, +dnl the return value for subnormal (denormalized) arguments is too large. +AC_DEFUN([gl_FUNC_LOGBF_WORKS], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether logbf works], [gl_cv_func_logbf_works], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include <float.h> +#include <math.h> +volatile float x; +int main () +{ + int i; + for (i = 1, x = 1.0f; i >= FLT_MIN_EXP; i--, x *= 0.5f) + ; + /* Here i = FLT_MIN_EXP - 1. Either x = 2^(i-1) is subnormal or x = 0.0. */ + if (x > 0.0f && !(logbf (x) == (float)(i - 1))) + return 1; + return 0; +} +]])], + [gl_cv_func_logbf_works=yes], + [gl_cv_func_logbf_works=no], + [case "$host_os" in + *gnu* | solaris*) gl_cv_func_logbf_works="guessing no";; + *) gl_cv_func_logbf_works="guessing yes";; + esac + ]) + ]) +]) diff --git a/m4/math_h.m4 b/m4/math_h.m4 index fe0cd0efaa..6f606651f3 100644 --- a/m4/math_h.m4 +++ b/m4/math_h.m4 @@ -1,4 +1,4 @@ -# math_h.m4 serial 108 +# math_h.m4 serial 109 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, @@ -46,7 +46,7 @@ AC_DEFUN([gl_MATH_H], fmod fmodf fmodl frexpf frexpl hypotf hypotl ldexpf ldexpl log logf logl log10 log10f log10l log1p log1pf log1pl log2 log2f log2l - logb + logb logbf modf modff modfl powf remainder remainderf remainderl rint rintf rintl round roundf roundl sinf sinl sinhf sqrtf sqrtl @@ -129,6 +129,7 @@ AC_DEFUN([gl_MATH_H_DEFAULTS], GNULIB_LOG2F=0; AC_SUBST([GNULIB_LOG2F]) GNULIB_LOG2L=0; AC_SUBST([GNULIB_LOG2L]) GNULIB_LOGB=0; AC_SUBST([GNULIB_LOGB]) + GNULIB_LOGBF=0; AC_SUBST([GNULIB_LOGBF]) GNULIB_MODF=0; AC_SUBST([GNULIB_MODF]) GNULIB_MODFF=0; AC_SUBST([GNULIB_MODFF]) GNULIB_MODFL=0; AC_SUBST([GNULIB_MODFL]) @@ -195,6 +196,7 @@ AC_DEFUN([gl_MATH_H_DEFAULTS], HAVE_LOG1P=1; AC_SUBST([HAVE_LOG1P]) HAVE_LOG1PF=1; AC_SUBST([HAVE_LOG1PF]) HAVE_LOG1PL=1; AC_SUBST([HAVE_LOG1PL]) + HAVE_LOGBF=1; AC_SUBST([HAVE_LOGBF]) HAVE_MODFF=1; AC_SUBST([HAVE_MODFF]) HAVE_MODFL=1; AC_SUBST([HAVE_MODFL]) HAVE_POWF=1; AC_SUBST([HAVE_POWF]) @@ -289,6 +291,7 @@ AC_DEFUN([gl_MATH_H_DEFAULTS], REPLACE_LOG2F=0; AC_SUBST([REPLACE_LOG2F]) REPLACE_LOG2L=0; AC_SUBST([REPLACE_LOG2L]) REPLACE_LOGB=0; AC_SUBST([REPLACE_LOGB]) + REPLACE_LOGBF=0; AC_SUBST([REPLACE_LOGBF]) REPLACE_MODF=0; AC_SUBST([REPLACE_MODF]) REPLACE_MODFF=0; AC_SUBST([REPLACE_MODFF]) REPLACE_MODFL=0; AC_SUBST([REPLACE_MODFL]) diff --git a/modules/logbf b/modules/logbf new file mode 100644 index 0000000000..b35c0b16fc --- /dev/null +++ b/modules/logbf @@ -0,0 +1,36 @@ +Description: +logbf() function: get exponent. + +Files: +lib/logbf.c +lib/logb.c +m4/logbf.m4 +m4/mathfunc.m4 + +Depends-on: +math +extensions +isfinite [test $HAVE_LOGBF = 0 || test $REPLACE_LOGBF = 1] +frexpf [test $HAVE_LOGBF = 0 || test $REPLACE_LOGBF = 1] +isnanf [test $HAVE_LOGBF = 0 || test $REPLACE_LOGBF = 1] + +configure.ac: +gl_FUNC_LOGBF +if test $HAVE_LOGBF = 0 || test $REPLACE_LOGBF = 1; then + AC_LIBOBJ([logbf]) +fi +gl_MATH_MODULE_INDICATOR([logbf]) + +Makefile.am: + +Include: +<math.h> + +Link: +$(LOGBF_LIBM) + +License: +LGPL + +Maintainer: +Bruno Haible diff --git a/modules/math b/modules/math index 26a80b0c0d..440aa78562 100644 --- a/modules/math +++ b/modules/math @@ -93,6 +93,7 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( -e 's/@''GNULIB_LOG2F''@/$(GNULIB_LOG2F)/g' \ -e 's/@''GNULIB_LOG2L''@/$(GNULIB_LOG2L)/g' \ -e 's/@''GNULIB_LOGB''@/$(GNULIB_LOGB)/g' \ + -e 's/@''GNULIB_LOGBF''@/$(GNULIB_LOGBF)/g' \ -e 's/@''GNULIB_MODF''@/$(GNULIB_MODF)/g' \ -e 's/@''GNULIB_MODFF''@/$(GNULIB_MODFF)/g' \ -e 's/@''GNULIB_MODFL''@/$(GNULIB_MODFL)/g' \ @@ -159,6 +160,7 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( -e 's|@''HAVE_LOG1P''@|$(HAVE_LOG1P)|g' \ -e 's|@''HAVE_LOG1PF''@|$(HAVE_LOG1PF)|g' \ -e 's|@''HAVE_LOG1PL''@|$(HAVE_LOG1PL)|g' \ + -e 's|@''HAVE_LOGBF''@|$(HAVE_LOGBF)|g' \ -e 's|@''HAVE_MODFF''@|$(HAVE_MODFF)|g' \ -e 's|@''HAVE_MODFL''@|$(HAVE_MODFL)|g' \ -e 's|@''HAVE_POWF''@|$(HAVE_POWF)|g' \ @@ -255,6 +257,7 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( -e 's|@''REPLACE_LOG2F''@|$(REPLACE_LOG2F)|g' \ -e 's|@''REPLACE_LOG2L''@|$(REPLACE_LOG2L)|g' \ -e 's|@''REPLACE_LOGB''@|$(REPLACE_LOGB)|g' \ + -e 's|@''REPLACE_LOGBF''@|$(REPLACE_LOGBF)|g' \ -e 's|@''REPLACE_MODF''@|$(REPLACE_MODF)|g' \ -e 's|@''REPLACE_MODFF''@|$(REPLACE_MODFF)|g' \ -e 's|@''REPLACE_MODFL''@|$(REPLACE_MODFL)|g' \ diff --git a/tests/test-math-c++.cc b/tests/test-math-c++.cc index 492e54a036..1821dd29de 100644 --- a/tests/test-math-c++.cc +++ b/tests/test-math-c++.cc @@ -251,6 +251,9 @@ SIGNATURE_CHECK (GNULIB_NAMESPACE::log2, double, (double)); SIGNATURE_CHECK (GNULIB_NAMESPACE::log2l, long double, (long double)); #endif +#if GNULIB_TEST_LOGBF +SIGNATURE_CHECK (GNULIB_NAMESPACE::logbf, float, (float)); +#endif #if GNULIB_TEST_LOGB SIGNATURE_CHECK (GNULIB_NAMESPACE::logb, double, (double)); #endif |