# HG changeset patch # User Bruno Haible # Date 1333421099 -7200 # Node ID 0f9a8ebc12c1caa699bc06e5061b7336dd228f6d # Parent 27c536025f33589ace7a95baea82e61d77240b3d 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. diff --git a/ChangeLog b/ChangeLog --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2012-04-02 Bruno Haible + + 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 logb tests: More tests. diff --git a/doc/posix-functions/logbf.texi b/doc/posix-functions/logbf.texi --- 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 --- /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 . */ + +#include + +/* Specification. */ +#include + +#define USE_FLOAT +#include "logb.c" diff --git a/lib/math.in.h b/lib/math.in.h --- a/lib/math.in.h +++ b/lib/math.in.h @@ -1388,6 +1388,29 @@ #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 --- /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 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 +#include +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 --- 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 @@ 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 @@ 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 @@ 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 @@ 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 --- /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: + + +Link: +$(LOGBF_LIBM) + +License: +LGPL + +Maintainer: +Bruno Haible diff --git a/modules/math b/modules/math --- a/modules/math +++ b/modules/math @@ -93,6 +93,7 @@ -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 @@ -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 @@ -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 --- a/tests/test-math-c++.cc +++ b/tests/test-math-c++.cc @@ -251,6 +251,9 @@ 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