Hello Benoit, > I was looking for a portable replacement of `trunc' for systems where > it is not be available. I saw that gnulib had that (http:// > www.gnu.org/software/gnulib/manual/html_node/trunc.html)
Well, there is a misunderstanding here. That doc says that 1) gnulib has no module supporting this function, 2) all known portability problems are in the "not fixed by gnulib" category. > invoked path/to/gnulib-tool --import trunc. It did what it was meant > to do but there was still no trace of `trunc' in my source tree Now wonder... But since trunc() is a particularly easy function to implement, I implemented this now. Also updating the doc. 2007-10-03 Bruno Haible <[EMAIL PROTECTED]> * modules/trunc: New file. * lib/trunc.c: New file. * m4/trunc.m4: New file. * lib/math.in.h (trunc): New declaration. * m4/math_h.m4 (gl_MATH_H_DEFAULTS): Initialize GNULIB_TRUNC and HAVE_DECL_TRUNC. * modules/math (Makefile.am): Substitute also GNULIB_TRUNC and HAVE_DECL_TRUNC. * doc/functions/trunc.texi: Mention the 'trunc' module. *** modules/trunc.orig 2003-09-23 19:59:22.000000000 +0200 --- modules/trunc 2007-10-04 02:22:04.000000000 +0200 *************** *** 0 **** --- 1,29 ---- + Description: + trunc() function: round towards zero. + + Files: + lib/trunc.c + m4/trunc.m4 + + Depends-on: + math + float + + configure.ac: + gl_FUNC_TRUNC + gl_MATH_MODULE_INDICATOR([trunc]) + + Makefile.am: + + Include: + <math.h> + + Link: + $(TRUNC_LIBM) + + License: + LGPL + + Maintainer: + Bruno Haible + *** lib/trunc.c.orig 2003-09-23 19:59:22.000000000 +0200 --- lib/trunc.c 2007-10-04 02:19:51.000000000 +0200 *************** *** 0 **** --- 1,68 ---- + /* Round towards zero. + 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 <[EMAIL PROTECTED]>, 2007. */ + + #include <config.h> + + /* Specification. */ + #include <math.h> + + #include <float.h> + + /* 2^(DBL_MANT_DIG-1). */ + static const double TWO_MANT_DIG = + /* Assume DBL_MANT_DIG <= 4 * 31. + Use the identity + n = floor(n/4) + floor((n+1)/4) + floor((n+2)/4) + floor((n+3)/4). */ + (double) (1U << ((DBL_MANT_DIG - 1) / 4)) + * (double) (1U << ((DBL_MANT_DIG - 1 + 1) / 4)) + * (double) (1U << ((DBL_MANT_DIG - 1 + 2) / 4)) + * (double) (1U << ((DBL_MANT_DIG - 1 + 3) / 4)); + + double + trunc (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; + + if (z > 0) + { + /* Round to the next integer (nearest or up or down, doesn't matter). */ + z += TWO_MANT_DIG; + z -= TWO_MANT_DIG; + /* Enforce rounding down. */ + if (z > y) + z -= 1.0; + } + else if (z < 0) + { + /* Round to the next integer (nearest or up or down, doesn't matter). */ + z -= TWO_MANT_DIG; + z += TWO_MANT_DIG; + /* Enforce rounding up. */ + if (z < y) + z += 1.0; + } + return z; + } *** m4/trunc.m4.orig 2003-09-23 19:59:22.000000000 +0200 --- m4/trunc.m4 2007-10-04 02:41:25.000000000 +0200 *************** *** 0 **** --- 1,46 ---- + # trunc.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_TRUNC], + [ + AC_REQUIRE([gl_MATH_H_DEFAULTS]) + dnl Test whether trunc() is declared. + AC_CHECK_DECLS([trunc], , , [#include <math.h>]) + if test "$ac_cv_have_decl_trunc" = yes; then + dnl Test whether trunc() can be used without libm. + TRUNC_LIBM=? + AC_TRY_LINK([ + #ifndef __NO_MATH_INLINES + # define __NO_MATH_INLINES 1 /* for glibc */ + #endif + #include <math.h> + double x;], + [x = trunc(x);], + [TRUNC_LIBM=]) + if test "$TRUNC_LIBM" = "?"; then + save_LIBS="$LIBS" + LIBS="$LIBS -lm" + AC_TRY_LINK([ + #ifndef __NO_MATH_INLINES + # define __NO_MATH_INLINES 1 /* for glibc */ + #endif + #include <math.h> + double x;], + [x = trunc(x);], + [TRUNC_LIBM="-lm"]) + LIBS="$save_LIBS" + fi + if test "$TRUNC_LIBM" = "?"; then + TRUNC_LIBM= + fi + else + HAVE_DECL_TRUNC=0 + AC_LIBOBJ([trunc]) + TRUNC_LIBM= + fi + AC_SUBST([HAVE_DECL_TRUNC]) + AC_SUBST([TRUNC_LIBM]) + ]) *** lib/math.in.h.orig 2007-10-04 03:07:40.000000000 +0200 --- lib/math.in.h 2007-10-04 02:00:57.000000000 +0200 *************** *** 211,216 **** --- 211,229 ---- tanl (x)) #endif + #if @GNULIB_TRUNC@ + # if [EMAIL PROTECTED]@ + # define trunc rpl_trunc + extern double trunc (double x); + # endif + #elif defined GNULIB_POSIXCHECK + # undef trunc + # define trunc(x) \ + (GL_LINK_WARNING ("trunc is unportable - " \ + "use gnulib module trunc for portability"), \ + trunc (x)) + #endif + #if @GNULIB_SIGNBIT@ # if @REPLACE_SIGNBIT@ *** m4/math_h.m4.orig 2007-10-04 03:07:40.000000000 +0200 --- m4/math_h.m4 2007-10-04 01:58:05.000000000 +0200 *************** *** 1,4 **** ! # math_h.m4 serial 5 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, --- 1,4 ---- ! # math_h.m4 serial 6 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, *************** *** 24,29 **** --- 24,30 ---- GNULIB_LDEXPL=0; AC_SUBST([GNULIB_LDEXPL]) GNULIB_MATHL=0; AC_SUBST([GNULIB_MATHL]) GNULIB_SIGNBIT=0; AC_SUBST([GNULIB_SIGNBIT]) + GNULIB_TRUNC=0; AC_SUBST([GNULIB_TRUNC]) dnl Assume proper GNU behavior unless another module says otherwise. HAVE_DECL_ACOSL=1; AC_SUBST([HAVE_DECL_ACOSL]) HAVE_DECL_ASINL=1; AC_SUBST([HAVE_DECL_ASINL]) *************** *** 38,43 **** --- 39,45 ---- HAVE_DECL_SINL=1; AC_SUBST([HAVE_DECL_SINL]) HAVE_DECL_SQRTL=1; AC_SUBST([HAVE_DECL_SQRTL]) HAVE_DECL_TANL=1; AC_SUBST([HAVE_DECL_TANL]) + HAVE_DECL_TRUNC=1; AC_SUBST([HAVE_DECL_TRUNC]) REPLACE_FREXP=0; AC_SUBST([REPLACE_FREXP]) REPLACE_FREXPL=0; AC_SUBST([REPLACE_FREXPL]) REPLACE_LDEXPL=0; AC_SUBST([REPLACE_LDEXPL]) *** modules/math.orig 2007-10-04 03:07:40.000000000 +0200 --- modules/math 2007-10-04 02:02:34.000000000 +0200 *************** *** 27,32 **** --- 27,33 ---- -e 's|@''GNULIB_LDEXPL''@|$(GNULIB_LDEXPL)|g' \ -e 's|@''GNULIB_MATHL''@|$(GNULIB_MATHL)|g' \ -e 's|@''GNULIB_SIGNBIT''@|$(GNULIB_SIGNBIT)|g' \ + -e 's|@''GNULIB_TRUNC''@|$(GNULIB_TRUNC)|g' \ -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' \ *************** *** 40,45 **** --- 41,47 ---- -e 's|@''HAVE_DECL_SINL''@|$(HAVE_DECL_SINL)|g' \ -e 's|@''HAVE_DECL_SQRTL''@|$(HAVE_DECL_SQRTL)|g' \ -e 's|@''HAVE_DECL_TANL''@|$(HAVE_DECL_TANL)|g' \ + -e 's|@''HAVE_DECL_TRUNC''@|$(HAVE_DECL_TRUNC)|g' \ -e 's|@''REPLACE_FREXP''@|$(REPLACE_FREXP)|g' \ -e 's|@''REPLACE_FREXPL''@|$(REPLACE_FREXPL)|g' \ -e 's|@''REPLACE_LDEXPL''@|$(REPLACE_LDEXPL)|g' \ *** doc/functions/trunc.texi.orig 2007-10-04 03:07:40.000000000 +0200 --- doc/functions/trunc.texi 2007-10-04 02:42:37.000000000 +0200 *************** *** 4,18 **** POSIX specification: @url{http://www.opengroup.org/susv3xsh/trunc.html} ! Gnulib module: --- Portability problems fixed by Gnulib: @itemize @end itemize Portability problems not fixed by Gnulib: @itemize - @item - This function is missing on some platforms: - FreeBSD 5.2.1, NetBSD 3.0, OpenBSD 3.8, Solaris 9, Interix 3.5. @end itemize --- 4,18 ---- POSIX specification: @url{http://www.opengroup.org/susv3xsh/trunc.html} ! Gnulib module: trunc Portability problems fixed by Gnulib: @itemize + @item + This function is missing on some platforms: + FreeBSD 5.2.1, NetBSD 3.0, OpenBSD 3.8, Solaris 9, Interix 3.5. @end itemize Portability problems not fixed by Gnulib: @itemize @end itemize