Paul Eggert <[EMAIL PROTECTED]> writes: > For other math.h functions it's a vital question, but you should be > able to implement trunc and round portably using ceil and floor, and > this should work correctly even for IEEE 754 hosts. Something like > this: > > double > rpl_trunc (double x) > { > return x < 0 ? ceil (x) : 0 < x ? floor (x) : x; > } > [...]
You are cleverer than me. Thanks. Here is my first stab at a module. I don't really know what I'm doing--I just tried to look at modules that did similar things for guidance, but it wasn't always clear to me which of several choices to pick--so feedback is very much appreciated. The following actually makes an unconditional wrapper around <math.h>, in the same way as the fcntl module does. I used floorl and ceill from the mathl module to implement roundl and truncl. I defined roundf and truncf to just call round and trunc, but another option would be to implement floorf and ceilf in the same way as roundl and truncl. I haven't actually tested the function implementations. It does pass "gnulib-tool --test math" for what it's worth, at least on my GNU/Linux system. Index: MODULES.html.sh =================================================================== RCS file: /cvsroot/gnulib/gnulib/MODULES.html.sh,v retrieving revision 1.161 diff -u -p -r1.161 MODULES.html.sh --- MODULES.html.sh 20 Nov 2006 22:07:27 -0000 1.161 +++ MODULES.html.sh 28 Nov 2006 06:08:45 -0000 @@ -1832,6 +1832,7 @@ func_all_modules () func_echo "$element" func_begin_table + func_module math func_module mathl func_end_table Index: lib/math_.h =================================================================== RCS file: lib/math_.h diff -N lib/math_.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ lib/math_.h 28 Nov 2006 06:08:45 -0000 @@ -0,0 +1,46 @@ +/* Provide a more complete set of math functions. + Copyright (C) 2006 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 Ben Pfaff. */ + +#ifndef _gl_MATH_H +#define _gl_MATH_H + +#include @ABSOLUTE_MATH_H@ +#include "mathl.h" + +#if !HAVE_DECL_ROUNDF +float roundf (float); +#endif +#if !HAVE_DECL_ROUND +double round (double); +#endif +#if !HAVE_DECL_ROUNDL +long double roundl (long double); +#endif + +#if !HAVE_DECL_TRUNCF +float truncf (float); +#endif +#if !HAVE_DECL_TRUNC +double trunc (double); +#endif +#if !HAVE_DECL_TRUNCL +long double truncl (long double); +#endif + +#endif /* _gl_MATH_H */ Index: lib/round.c =================================================================== RCS file: lib/round.c diff -N lib/round.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ lib/round.c 28 Nov 2006 06:08:45 -0000 @@ -0,0 +1,75 @@ +/* round.c - portable implementation of round functions. + + Copyright (C) 2006 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 Paul Eggert and Ben Pfaff. */ + +#include <math.h> + +#if !HAVE_ROUNDF +float +roundf (float x) +{ + return round (x); +} +#endif /* !HAVE_ROUND */ + +#if !HAVE_ROUND +double +round (double x) +{ + if (x < 0) + { + double t = ceil (x); + if (0.5 <= t - x) + t--; + return t; + } + else if (0 < x) + { + double t = floor (x); + if (0.5 <= x - t) + t++; + return t; + } + else + return x; +} +#endif /* !HAVE_ROUND */ + +#if !HAVE_ROUNDL +long double +roundl (long double x) +{ + if (x < 0) + { + long double t = ceill (x); + if (0.5 <= t - x) + t--; + return t; + } + else if (0 < x) + { + long double t = floorl (x); + if (0.5 <= x - t) + t++; + return t; + } + else + return x; +} +#endif /* !HAVE_ROUNDL */ Index: lib/trunc.c =================================================================== RCS file: lib/trunc.c diff -N lib/trunc.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ lib/trunc.c 28 Nov 2006 06:08:45 -0000 @@ -0,0 +1,45 @@ +/* trunc.c - portable implementation of trunc functions. + + Copyright (C) 2006 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 Paul Eggert and Ben Pfaff. */ + +#include <math.h> + +#if !HAVE_TRUNCF +float +truncf (float x) +{ + return trunc (x); +} +#endif /* !HAVE_TRUNC */ + +#if !HAVE_TRUNC +double +trunc (double x) +{ + return x < 0 ? ceil (x) : 0 < x ? floor (x) : x; +} +#endif /* !HAVE_TRUNC */ + +#if !HAVE_TRUNCL +long double +truncl (long double x) +{ + return x < 0 ? ceill (x) : 0 < x ? floorl (x) : x; +} +#endif /* !HAVE_TRUNCL */ Index: m4/math.m4 =================================================================== RCS file: m4/math.m4 diff -N m4/math.m4 --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ m4/math.m4 28 Nov 2006 06:08:45 -0000 @@ -0,0 +1,24 @@ +# math.m4 serial 1 +dnl Copyright (C) 2006 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_MATH_H], +[ + dnl Persuade glibc to declare C99 math functions. + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + + AC_CHECK_LIB(m, atan) + + AC_CHECK_DECLS([roundf, round, roundl, + truncf, trunc, truncl], , , [#include <math.h>]) + AC_CHECK_FUNCS([roundf round roundl], , [AC_LIBOBJ(round)]) + AC_CHECK_FUNCS([truncf trunc truncl], , [AC_LIBOBJ(trunc)]) + + gl_ABSOLUTE_HEADER([math.h]) + ABSOLUTE_MATH_H=\"$gl_cv_absolute_math_h\" + AC_SUBST([ABSOLUTE_MATH_H]) + MATH_H='math.h' + AC_SUBST([MATH_H]) +]) Index: modules/math =================================================================== RCS file: modules/math diff -N modules/math --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ modules/math 28 Nov 2006 06:08:46 -0000 @@ -0,0 +1,39 @@ +Description: +C99 functions for rounding floating-point numbers. + +Files: +lib/math_.h +lib/round.c +lib/trunc.c +m4/absolute-header.m4 +m4/math.m4 + +Depends-on: +extensions +mathl + +configure.ac: +gl_MATH_H + +Makefile.am: +BUILT_SOURCES += $(MATH_H) + +# Create a wrapper around <math.h> that declares any missing C99 +# functions. +math.h: math_.h + rm -f [EMAIL PROTECTED] $@ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's|@''ABSOLUTE_MATH_H''@|$(ABSOLUTE_MATH_H)|g' \ + < $(srcdir)/math_.h; \ + } > [EMAIL PROTECTED] + mv [EMAIL PROTECTED] $@ +MOSTLYCLEANFILES += math.h math.h-t + +Include: +#include <math.h> + +License: +GPL + +Maintainer: +Ben Pfaff <[EMAIL PROTECTED]> -- Ben Pfaff email: [EMAIL PROTECTED] web: http://benpfaff.org