The truncf() function can be implemented just like trunc(). 2007-10-04 Bruno Haible <[EMAIL PROTECTED]>
* modules/truncf: New file. * lib/trunc.c: Make paramerizable through USE_* macros. * lib/truncf.c: New file. * m4/truncf.m4: New file. * lib/math.in.h (truncf): New declaration. * m4/math_h.m4 (gl_MATH_H_DEFAULTS): Initialize GNULIB_TRUNCF and HAVE_DECL_TRUNCF. * modules/math (Makefile.am): Substitute also GNULIB_TRUNCF and HAVE_DECL_TRUNCF. * doc/functions/truncf.texi: Mention the 'truncf' module. *** doc/functions/truncf.texi.orig 2007-10-05 01:05:03.000000000 +0200 --- doc/functions/truncf.texi 2007-10-04 12:38:09.000000000 +0200 *************** *** 4,18 **** POSIX specification: @url{http://www.opengroup.org/susv3xsh/truncf.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, AIX 5.1, HP-UX 11, Solaris 9, Interix 3.5. @end itemize --- 4,18 ---- POSIX specification: @url{http://www.opengroup.org/susv3xsh/truncf.html} ! Gnulib module: truncf Portability problems fixed by Gnulib: @itemize + @item + This function is missing on some platforms: + FreeBSD 5.2.1, NetBSD 3.0, OpenBSD 3.8, AIX 5.1, HP-UX 11, Solaris 9, Interix 3.5. @end itemize Portability problems not fixed by Gnulib: @itemize @end itemize *** lib/math.in.h.orig 2007-10-05 01:05:03.000000000 +0200 --- lib/math.in.h 2007-10-05 00:22:13.000000000 +0200 *************** *** 65,70 **** --- 65,71 ---- acosl (x)) #endif + #if @GNULIB_MATHL@ || [EMAIL PROTECTED]@ extern long double asinl (long double x); #endif *************** *** 76,81 **** --- 77,83 ---- asinl (x)) #endif + #if @GNULIB_MATHL@ || [EMAIL PROTECTED]@ extern long double atanl (long double x); #endif *************** *** 87,92 **** --- 89,95 ---- atanl (x)) #endif + #if @GNULIB_MATHL@ || [EMAIL PROTECTED]@ extern long double ceill (long double x); #endif *************** *** 98,103 **** --- 101,107 ---- ceill (x)) #endif + #if @GNULIB_MATHL@ || [EMAIL PROTECTED]@ extern long double cosl (long double x); #endif *************** *** 109,114 **** --- 113,119 ---- cosl (x)) #endif + #if @GNULIB_MATHL@ || [EMAIL PROTECTED]@ extern long double expl (long double x); #endif *************** *** 120,125 **** --- 125,131 ---- expl (x)) #endif + #if @GNULIB_MATHL@ || [EMAIL PROTECTED]@ extern long double floorl (long double x); #endif *************** *** 131,136 **** --- 137,143 ---- floorl (x)) #endif + /* Write x as x = mantissa * 2^exp where *************** *** 152,157 **** --- 159,165 ---- frexpl (x, e)) #endif + /* Return x * 2^exp. */ #if @GNULIB_LDEXPL@ && @REPLACE_LDEXPL@ # define ldexpl rpl_ldexpl *************** *** 167,172 **** --- 175,181 ---- ldexpl (x, e)) #endif + #if @GNULIB_MATHL@ || [EMAIL PROTECTED]@ extern long double logl (long double x); #endif *************** *** 178,183 **** --- 187,193 ---- logl (x)) #endif + #if @GNULIB_MATHL@ || [EMAIL PROTECTED]@ extern long double sinl (long double x); #endif *************** *** 189,194 **** --- 199,205 ---- sinl (x)) #endif + #if @GNULIB_MATHL@ || [EMAIL PROTECTED]@ extern long double sqrtl (long double x); #endif *************** *** 200,205 **** --- 211,217 ---- sqrtl (x)) #endif + #if @GNULIB_MATHL@ || [EMAIL PROTECTED]@ extern long double tanl (long double x); #endif *************** *** 211,216 **** --- 223,242 ---- tanl (x)) #endif + + #if @GNULIB_TRUNCF@ + # if [EMAIL PROTECTED]@ + # define truncf rpl_truncf + extern float truncf (float x); + # endif + #elif defined GNULIB_POSIXCHECK + # undef truncf + # define truncf(x) \ + (GL_LINK_WARNING ("truncf is unportable - " \ + "use gnulib module truncf for portability"), \ + truncf (x)) + #endif + #if @GNULIB_TRUNC@ # if [EMAIL PROTECTED]@ # define trunc rpl_trunc *** lib/trunc.c.orig 2007-10-05 01:05:03.000000000 +0200 --- lib/trunc.c 2007-10-05 00:57:25.000000000 +0200 *************** *** 24,41 **** #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 --- 24,59 ---- #include <float.h> ! #ifdef USE_LONG_DOUBLE ! # define FUNC truncl ! # define DOUBLE long double ! # define MANT_DIG LDBL_MANT_DIG ! # define L_(literal) literal##L ! #elif ! defined USE_FLOAT ! # define FUNC trunc ! # define DOUBLE double ! # define MANT_DIG DBL_MANT_DIG ! # define L_(literal) literal ! #else /* defined USE_FLOAT */ ! # define FUNC truncf ! # 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 *************** *** 43,68 **** 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; } --- 61,86 ---- 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 > L_(0.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 -= L_(1.0); } ! else if (z < L_(0.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 += L_(1.0); } return z; } Changing permissions from . to 100644 *** lib/truncf.c.orig 2003-09-23 19:59:22.000000000 +0200 --- lib/truncf.c 2007-10-04 12:27:09.000000000 +0200 *************** *** 0 **** --- 1,21 ---- + /* 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. */ + + #define USE_FLOAT + #include "trunc.c" *** m4/math_h.m4.orig 2007-10-05 01:05:03.000000000 +0200 --- m4/math_h.m4 2007-10-04 12:46:10.000000000 +0200 *************** *** 25,30 **** --- 25,31 ---- GNULIB_MATHL=0; AC_SUBST([GNULIB_MATHL]) GNULIB_SIGNBIT=0; AC_SUBST([GNULIB_SIGNBIT]) GNULIB_TRUNC=0; AC_SUBST([GNULIB_TRUNC]) + GNULIB_TRUNCF=0; AC_SUBST([GNULIB_TRUNCF]) 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]) *************** *** 40,45 **** --- 41,47 ---- 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]) + HAVE_DECL_TRUNCF=1; AC_SUBST([HAVE_DECL_TRUNCF]) REPLACE_FREXP=0; AC_SUBST([REPLACE_FREXP]) REPLACE_FREXPL=0; AC_SUBST([REPLACE_FREXPL]) REPLACE_LDEXPL=0; AC_SUBST([REPLACE_LDEXPL]) Changing permissions from . to 100644 *** m4/truncf.m4.orig 2003-09-23 19:59:22.000000000 +0200 --- m4/truncf.m4 2007-10-05 01:01:19.000000000 +0200 *************** *** 0 **** --- 1,48 ---- + # truncf.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_TRUNCF], + [ + AC_REQUIRE([gl_MATH_H_DEFAULTS]) + dnl Persuade glibc <math.h> to declare truncf(). + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + dnl Test whether truncf() is declared. + AC_CHECK_DECLS([truncf], , , [#include <math.h>]) + if test "$ac_cv_have_decl_truncf" = yes; then + dnl Test whether truncf() can be used without libm. + TRUNCF_LIBM=? + AC_TRY_LINK([ + #ifndef __NO_MATH_INLINES + # define __NO_MATH_INLINES 1 /* for glibc */ + #endif + #include <math.h> + float x;], + [x = truncf(x);], + [TRUNCF_LIBM=]) + if test "$TRUNCF_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> + float x;], + [x = truncf(x);], + [TRUNCF_LIBM="-lm"]) + LIBS="$save_LIBS" + fi + if test "$TRUNCF_LIBM" = "?"; then + TRUNCF_LIBM= + fi + else + HAVE_DECL_TRUNCF=0 + AC_LIBOBJ([truncf]) + TRUNCF_LIBM= + fi + AC_SUBST([HAVE_DECL_TRUNCF]) + AC_SUBST([TRUNCF_LIBM]) + ]) *** modules/math.orig 2007-10-05 01:05:03.000000000 +0200 --- modules/math 2007-10-04 12:45:48.000000000 +0200 *************** *** 28,33 **** --- 28,34 ---- -e 's|@''GNULIB_MATHL''@|$(GNULIB_MATHL)|g' \ -e 's|@''GNULIB_SIGNBIT''@|$(GNULIB_SIGNBIT)|g' \ -e 's|@''GNULIB_TRUNC''@|$(GNULIB_TRUNC)|g' \ + -e 's|@''GNULIB_TRUNCF''@|$(GNULIB_TRUNCF)|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' \ *************** *** 42,47 **** --- 43,49 ---- -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|@''HAVE_DECL_TRUNCF''@|$(HAVE_DECL_TRUNCF)|g' \ -e 's|@''REPLACE_FREXP''@|$(REPLACE_FREXP)|g' \ -e 's|@''REPLACE_FREXPL''@|$(REPLACE_FREXPL)|g' \ -e 's|@''REPLACE_LDEXPL''@|$(REPLACE_LDEXPL)|g' \ Changing permissions from . to 100644 *** modules/truncf.orig 2003-09-23 19:59:22.000000000 +0200 --- modules/truncf 2007-10-05 00:54:39.000000000 +0200 *************** *** 0 **** --- 1,31 ---- + Description: + truncf() function: round towards zero. + + Files: + lib/truncf.c + lib/trunc.c + m4/truncf.m4 + + Depends-on: + math + extensions + float + + configure.ac: + gl_FUNC_TRUNCF + gl_MATH_MODULE_INDICATOR([truncf]) + + Makefile.am: + + Include: + <math.h> + + Link: + $(TRUNCF_LIBM) + + License: + LGPL + + Maintainer: + Bruno Haible +