From b064d497f3f612ba40acccbe3dcaccec7980ee39 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Fri, 5 Oct 2007 03:43:42 +0200 Subject: [PATCH] New module 'ceilf'. --- ChangeLog | 13 ++++++++ doc/functions/ceilf.texi | 8 ++--- lib/ceil.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++ lib/ceilf.c | 21 ++++++++++++ lib/math.in.h | 13 ++++++++ m4/ceilf.m4 | 48 ++++++++++++++++++++++++++++ m4/math_h.m4 | 2 ++ modules/ceilf | 31 ++++++++++++++++++ modules/math | 2 ++ 9 files changed, 217 insertions(+), 4 deletions(-) create mode 100644 lib/ceil.c create mode 100644 lib/ceilf.c create mode 100644 m4/ceilf.m4 create mode 100644 modules/ceilf diff --git a/ChangeLog b/ChangeLog index ae0545ccd..8c8720c51 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,18 @@ 2007-10-04 Bruno Haible + * modules/ceilf: New file. + * lib/ceil.c: New file. + * lib/ceilf.c: New file. + * m4/ceilf.m4: New file. + * lib/math.in.h (ceilf): New declaration. + * m4/math_h.m4 (gl_MATH_H_DEFAULTS): Initialize GNULIB_CEILF and + HAVE_DECL_CEILF. + * modules/math (Makefile.am): Substitute also GNULIB_CEILF and + HAVE_DECL_CEILF. + * doc/functions/ceilf.texi: Mention the 'ceilf' module. + +2007-10-04 Bruno Haible + * modules/floorl-tests: New file. * tests/test-floorl.c: New file. diff --git a/doc/functions/ceilf.texi b/doc/functions/ceilf.texi index 50c1887e5..80e34e4a4 100644 --- a/doc/functions/ceilf.texi +++ b/doc/functions/ceilf.texi @@ -4,15 +4,15 @@ POSIX specification: @url{http://www.opengroup.org/susv3xsh/ceilf.html} -Gnulib module: --- +Gnulib module: ceilf Portability problems fixed by Gnulib: @itemize +@item +This function is missing on some platforms: +AIX 5.1, HP-UX 11, Solaris 9. @end itemize Portability problems not fixed by Gnulib: @itemize -@item -This function is missing on some platforms: -AIX 5.1, HP-UX 11, Solaris 9. @end itemize diff --git a/lib/ceil.c b/lib/ceil.c new file mode 100644 index 000000000..ced224ca8 --- /dev/null +++ b/lib/ceil.c @@ -0,0 +1,83 @@ +/* Round towards positive infinity. + Copyright (C) 2007 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 2, 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, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Bruno Haible , 2007. */ + +#include + +/* Specification. */ +#include + +#include + +#ifdef USE_LONG_DOUBLE +# define FUNC ceill +# define DOUBLE long double +# define MANT_DIG LDBL_MANT_DIG +# define L_(literal) literal##L +#elif ! defined USE_FLOAT +# define FUNC ceil +# define DOUBLE double +# define MANT_DIG DBL_MANT_DIG +# define L_(literal) literal +#else /* defined USE_FLOAT */ +# define FUNC ceilf +# define DOUBLE float +# define MANT_DIG FLT_MANT_DIG +# define L_(literal) literal##f +#endif + +/* 2^(MANT_DIG-1). */ +static const double TWO_MANT_DIG = + /* Assume MANT_DIG <= 5 * 31. + Use the identity + n = floor(n/5) + floor((n+1)/5) + ... + floor((n+4)/5). */ + (DOUBLE) (1U << ((MANT_DIG - 1) / 5)) + * (DOUBLE) (1U << ((MANT_DIG - 1 + 1) / 5)) + * (DOUBLE) (1U << ((MANT_DIG - 1 + 2) / 5)) + * (DOUBLE) (1U << ((MANT_DIG - 1 + 3) / 5)) + * (DOUBLE) (1U << ((MANT_DIG - 1 + 4) / 5)); + +DOUBLE +FUNC (DOUBLE x) +{ + /* The use of 'volatile' guarantees that excess precision bits are dropped + at each addition step and before the following comparison at the caller's + site. It is necessary on x86 systems where double-floats are not IEEE + compliant by default, to avoid that the results become platform and compiler + option dependent. 'volatile' is a portable alternative to gcc's + -ffloat-store option. */ + volatile DOUBLE y = x; + volatile DOUBLE z = y; + + /* Round to the next integer (nearest or up or down, doesn't matter). */ + if (z > L_(0.0)) + { + z += TWO_MANT_DIG; + z -= TWO_MANT_DIG; + } + else if (z < L_(0.0)) + { + z -= TWO_MANT_DIG; + z += TWO_MANT_DIG; + } + /* Enforce rounding up. */ + if (z < y) + z += L_(1.0); + + return z; +} diff --git a/lib/ceilf.c b/lib/ceilf.c new file mode 100644 index 000000000..8f6db345a --- /dev/null +++ b/lib/ceilf.c @@ -0,0 +1,21 @@ +/* Round towards positive infinity. + Copyright (C) 2007 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 2, 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, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Bruno Haible , 2007. */ + +#define USE_FLOAT +#include "ceil.c" diff --git a/lib/math.in.h b/lib/math.in.h index 490524276..ef0682af5 100644 --- a/lib/math.in.h +++ b/lib/math.in.h @@ -90,6 +90,19 @@ extern long double atanl (long double x); #endif +#if @GNULIB_CEILF@ +# if !@HAVE_DECL_CEILF@ +# define ceilf rpl_ceilf +extern float ceilf (float x); +# endif +#elif defined GNULIB_POSIXCHECK +# undef ceilf +# define ceilf(x) \ + (GL_LINK_WARNING ("ceilf is unportable - " \ + "use gnulib module ceilf for portability"), \ + ceilf (x)) +#endif + #if @GNULIB_MATHL@ || !@HAVE_DECL_CEILL@ extern long double ceill (long double x); #endif diff --git a/m4/ceilf.m4 b/m4/ceilf.m4 new file mode 100644 index 000000000..65f10bede --- /dev/null +++ b/m4/ceilf.m4 @@ -0,0 +1,48 @@ +# ceilf.m4 serial 1 +dnl Copyright (C) 2007 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_CEILF], +[ + AC_REQUIRE([gl_MATH_H_DEFAULTS]) + dnl Persuade glibc to declare ceilf(). + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + dnl Test whether ceilf() is declared. + AC_CHECK_DECLS([ceilf], , , [#include ]) + if test "$ac_cv_have_decl_ceilf" = yes; then + dnl Test whether ceilf() can be used without libm. + CEILF_LIBM=? + AC_TRY_LINK([ + #ifndef __NO_MATH_INLINES + # define __NO_MATH_INLINES 1 /* for glibc */ + #endif + #include + float x;], + [x = ceilf(x);], + [CEILF_LIBM=]) + if test "$CEILF_LIBM" = "?"; then + save_LIBS="$LIBS" + LIBS="$LIBS -lm" + AC_TRY_LINK([ + #ifndef __NO_MATH_INLINES + # define __NO_MATH_INLINES 1 /* for glibc */ + #endif + #include + float x;], + [x = ceilf(x);], + [CEILF_LIBM="-lm"]) + LIBS="$save_LIBS" + fi + if test "$CEILF_LIBM" = "?"; then + CEILF_LIBM= + fi + else + HAVE_DECL_CEILF=0 + AC_LIBOBJ([ceilf]) + CEILF_LIBM= + fi + AC_SUBST([HAVE_DECL_CEILF]) + AC_SUBST([CEILF_LIBM]) +]) diff --git a/m4/math_h.m4 b/m4/math_h.m4 index 3d12eb3be..76d5dbc59 100644 --- a/m4/math_h.m4 +++ b/m4/math_h.m4 @@ -19,6 +19,7 @@ AC_DEFUN([gl_MATH_MODULE_INDICATOR], AC_DEFUN([gl_MATH_H_DEFAULTS], [ + GNULIB_CEILF=0; AC_SUBST([GNULIB_CEILF]) GNULIB_FLOORF=0; AC_SUBST([GNULIB_FLOORF]) GNULIB_FLOORL=0; AC_SUBST([GNULIB_FLOORL]) GNULIB_FREXP=0; AC_SUBST([GNULIB_FREXP]) @@ -33,6 +34,7 @@ AC_DEFUN([gl_MATH_H_DEFAULTS], HAVE_DECL_ACOSL=1; AC_SUBST([HAVE_DECL_ACOSL]) HAVE_DECL_ASINL=1; AC_SUBST([HAVE_DECL_ASINL]) HAVE_DECL_ATANL=1; AC_SUBST([HAVE_DECL_ATANL]) + HAVE_DECL_CEILF=1; AC_SUBST([HAVE_DECL_CEILF]) HAVE_DECL_CEILL=1; AC_SUBST([HAVE_DECL_CEILL]) HAVE_DECL_COSL=1; AC_SUBST([HAVE_DECL_COSL]) HAVE_DECL_EXPL=1; AC_SUBST([HAVE_DECL_EXPL]) diff --git a/modules/ceilf b/modules/ceilf new file mode 100644 index 000000000..3c0082c78 --- /dev/null +++ b/modules/ceilf @@ -0,0 +1,31 @@ +Description: +ceilf() function: round towards positive infinity. + +Files: +lib/ceilf.c +lib/ceil.c +m4/ceilf.m4 + +Depends-on: +math +extensions +float + +configure.ac: +gl_FUNC_CEILF +gl_MATH_MODULE_INDICATOR([ceilf]) + +Makefile.am: + +Include: + + +Link: +$(CEILF_LIBM) + +License: +LGPL + +Maintainer: +Bruno Haible + diff --git a/modules/math b/modules/math index a892db301..0a41904d6 100644 --- a/modules/math +++ b/modules/math @@ -22,6 +22,7 @@ math.h: math.in.h { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ sed -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ -e 's|@''NEXT_MATH_H''@|$(NEXT_MATH_H)|g' \ + -e 's|@''GNULIB_CEILF''@|$(GNULIB_CEILF)|g' \ -e 's|@''GNULIB_FLOORF''@|$(GNULIB_FLOORF)|g' \ -e 's|@''GNULIB_FLOORL''@|$(GNULIB_FLOORL)|g' \ -e 's|@''GNULIB_FREXP''@|$(GNULIB_FREXP)|g' \ @@ -35,6 +36,7 @@ math.h: math.in.h -e 's|@''HAVE_DECL_ACOSL''@|$(HAVE_DECL_ACOSL)|g' \ -e 's|@''HAVE_DECL_ASINL''@|$(HAVE_DECL_ASINL)|g' \ -e 's|@''HAVE_DECL_ATANL''@|$(HAVE_DECL_ATANL)|g' \ + -e 's|@''HAVE_DECL_CEILF''@|$(HAVE_DECL_CEILF)|g' \ -e 's|@''HAVE_DECL_CEILL''@|$(HAVE_DECL_CEILL)|g' \ -e 's|@''HAVE_DECL_COSL''@|$(HAVE_DECL_COSL)|g' \ -e 's|@''HAVE_DECL_EXPL''@|$(HAVE_DECL_EXPL)|g' \ -- 2.11.0