Mercurial > hg > octave-lyh > gnulib-hg
changeset 10265:ecc1f86df809
Add isnand module.
author | Ben Pfaff <blp@cs.stanford.edu> |
---|---|
date | Sat, 12 Jul 2008 10:45:22 -0700 |
parents | ebb7ea0c94e8 |
children | c0565d2cba32 |
files | ChangeLog MODULES.html.sh lib/isnand.h m4/isnand.m4 modules/isnand modules/isnand-nolibm-tests modules/isnand-tests tests/test-isnand-nolibm.c tests/test-isnand.c tests/test-isnand.h |
diffstat | 10 files changed, 266 insertions(+), 65 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2008-07-10 Ben Pfaff <blp@gnu.org> + + Add isnand module. + * lib/isnand.h: New file. + * m4/isnand.m4 (gl_FUNC_ISNAND): New macro. + (gl_FUNC_ISNAND_NO_LIBM): Split partially into new macro + gl_HAVE_ISNAND_NO_LIBM so that gl_FUNC_ISNAND can use that + functionality also. + (gl_BUILD_ISNAND): New macro used by gl_FUNC_ISNAND, + gl_FUNC_ISNAND_NO_LIBM, and gl_FUNC_ISNAN. + (gl_HAVE_ISNAND_IN_LIBM): New macro. + * modules/isnand: New file. + * modules/isnand-tests: New file. + * modules/isnand-nolibm-tests: Add tests/test-isnand.h to list of + files. + * tests/test-isnand-nolibm.c: factored most of its contents into + new file tests/test-isnand.h. + * tests/test-isnand.h: New file. + * tests/test-isnand.c: New file. + * MODULES.html.sh: Mention new module. + 2008-07-10 Ben Pfaff <blp@gnu.org> * lib/isnanf.h: Rename lib/isnanf-nolibm.h.
--- a/MODULES.html.sh +++ b/MODULES.html.sh @@ -2000,6 +2000,7 @@ func_module frexpl-nolibm func_module isfinite func_module isnanf-nolibm + func_module isnand func_module isnand-nolibm func_module isnanl func_module isnanl-nolibm
new file mode 100644 --- /dev/null +++ b/lib/isnand.h @@ -0,0 +1,33 @@ +/* Test for NaN. + Copyright (C) 2007-2008 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 <http://www.gnu.org/licenses/>. */ + +#if HAVE_ISNAND +/* Get declaration of isnan macro. */ +# include <math.h> +# if __GNUC__ >= 4 + /* GCC 4.0 and newer provides three built-ins for isnan. */ +# undef isnand +# define isnand(x) __builtin_isnan ((double)(x)) +# else +# undef isnand +# define isnand(x) isnan ((double)(x)) +# endif +#else +/* Test whether X is a NaN. */ +# undef isnand +# define isnand rpl_isnand +extern int isnand (double x); +#endif
--- a/m4/isnand.m4 +++ b/m4/isnand.m4 @@ -1,13 +1,80 @@ -# isnand.m4 serial 2 +# isnand.m4 serial 3 dnl Copyright (C) 2007-2008 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. +dnl Check how to get or define isnand(). +AC_DEFUN([gl_FUNC_ISNAND], +[ + ISNAND_LIBM= + gl_HAVE_ISNAND_NO_LIBM + if test $gl_cv_func_isnand_no_libm = no; then + gl_HAVE_ISNAND_IN_LIBM + if test $gl_cv_func_isnand_in_libm = yes; then + ISNAND_LIBM=-lm + fi + fi + dnl The variable gl_func_isnand set here is used by isnan.m4. + if test $gl_cv_func_isnand_no_libm = yes \ + || test $gl_cv_func_isnand_in_libm = yes; then + gl_func_isnand=yes + AC_DEFINE([HAVE_ISNAND], 1, + [Define if the isnan(double) function is available.]) + else + gl_func_isnand=no + gl_BUILD_ISNAND + fi + AC_SUBST([ISNAND_LIBM]) +]) + dnl Check how to get or define isnand() without linking with libm. AC_DEFUN([gl_FUNC_ISNAND_NO_LIBM], [ + gl_HAVE_ISNAND_NO_LIBM + if test $gl_cv_func_isnand_no_libm = yes; then + AC_DEFINE([HAVE_ISNAND_IN_LIBC], 1, + [Define if the isnan(double) function is available in libc.]) + else + gl_BUILD_ISNAND + fi +]) + +dnl Pull in replacement isnand definition. +AC_DEFUN([gl_BUILD_ISNAND], +[ + AC_LIBOBJ([isnand]) + gl_DOUBLE_EXPONENT_LOCATION +]) + +dnl Test whether isnand() can be used with libm. + +AC_DEFUN([gl_HAVE_ISNAND_IN_LIBM], +[ + AC_CACHE_CHECK([whether isnan(double) can be used with libm], + [gl_cv_func_isnand_in_libm], + [ + save_LIBS="$LIBS" + LIBS="$LIBS -lm" + AC_TRY_LINK([#include <math.h> + #if __GNUC__ >= 4 + # undef isnand + # define isnand(x) __builtin_isnand ((double)(x)) + #elif defined isnan + # undef isnand + # define isnand(x) isnan ((double)(x)) + #endif + double x;], + [return isnand (x);], + [gl_cv_func_isnand_in_libm=yes], + [gl_cv_func_isnand_in_libm=no]) + LIBS="$save_LIBS" + ]) +]) + +AC_DEFUN([gl_HAVE_ISNAND_NO_LIBM], +[ AC_CACHE_CHECK([whether isnan(double) can be used without linking with libm], [gl_cv_func_isnand_no_libm], [ @@ -24,13 +91,6 @@ [gl_cv_func_isnand_no_libm=yes], [gl_cv_func_isnand_no_libm=no]) ]) - if test $gl_cv_func_isnand_no_libm = yes; then - AC_DEFINE([HAVE_ISNAND_IN_LIBC], 1, - [Define if the isnan(double) function is available in libc.]) - else - AC_LIBOBJ([isnand]) - gl_DOUBLE_EXPONENT_LOCATION - fi ]) AC_DEFUN([gl_DOUBLE_EXPONENT_LOCATION],
new file mode 100644 --- /dev/null +++ b/modules/isnand @@ -0,0 +1,30 @@ +Description: +isnand() function: test for NaN. + +Files: +lib/isnand.h +lib/isnand.c +lib/isnan.c +lib/float+.h +m4/isnand.m4 + +Depends-on: +fpieee + +configure.ac: +gl_FUNC_ISNAND + +Makefile.am: + +Include: +#include "isnand.h" + +Link: +$(ISNAND_LIBM) + +License: +LGPL + +Maintainer: +Bruno Haible +
--- a/modules/isnand-nolibm-tests +++ b/modules/isnand-nolibm-tests @@ -1,5 +1,6 @@ Files: tests/test-isnand-nolibm.c +tests/test-isnand.h tests/nan.h Depends-on:
new file mode 100644 --- /dev/null +++ b/modules/isnand-tests @@ -0,0 +1,15 @@ +Files: +tests/test-isnand.c +tests/test-isnand.h +tests/nan.h + +Depends-on: + +configure.ac: +gl_DOUBLE_EXPONENT_LOCATION + +Makefile.am: +TESTS += test-isnand +check_PROGRAMS += test-isnand +test_isnand_LDADD = $(LDADD) @ISNAND_LIBM@ +
--- a/tests/test-isnand-nolibm.c +++ b/tests/test-isnand-nolibm.c @@ -14,65 +14,9 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* Written by Bruno Haible <bruno@clisp.org>, 2007. */ - #include <config.h> #include "isnand-nolibm.h" -#include <limits.h> -#include <stdio.h> -#include <stdlib.h> - -#include "nan.h" - -#define ASSERT(expr) \ - do \ - { \ - if (!(expr)) \ - { \ - fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \ - fflush (stderr); \ - abort (); \ - } \ - } \ - while (0) +#include "test-isnand.h" -int -main () -{ - /* Finite values. */ - ASSERT (!isnand (3.141)); - ASSERT (!isnand (3.141e30)); - ASSERT (!isnand (3.141e-30)); - ASSERT (!isnand (-2.718)); - ASSERT (!isnand (-2.718e30)); - ASSERT (!isnand (-2.718e-30)); - ASSERT (!isnand (0.0)); - ASSERT (!isnand (-0.0)); - /* Infinite values. */ - ASSERT (!isnand (1.0 / 0.0)); - ASSERT (!isnand (-1.0 / 0.0)); - /* Quiet NaN. */ - ASSERT (isnand (NaNd ())); -#if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT - /* Signalling NaN. */ - { - #define NWORDS \ - ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) - typedef union { double value; unsigned int word[NWORDS]; } memory_double; - memory_double m; - m.value = NaNd (); -# if DBL_EXPBIT0_BIT > 0 - m.word[DBL_EXPBIT0_WORD] ^= (unsigned int) 1 << (DBL_EXPBIT0_BIT - 1); -# else - m.word[DBL_EXPBIT0_WORD + (DBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)] - ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1); -# endif - m.word[DBL_EXPBIT0_WORD + (DBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)] - |= (unsigned int) 1 << DBL_EXPBIT0_BIT; - ASSERT (isnand (m.value)); - } -#endif - return 0; -}
new file mode 100644 --- /dev/null +++ b/tests/test-isnand.c @@ -0,0 +1,22 @@ +/* Test of isnand() substitute. + Copyright (C) 2007-2008 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 <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +#include "isnand.h" + +#include "test-isnand.h" +
new file mode 100644 --- /dev/null +++ b/tests/test-isnand.h @@ -0,0 +1,74 @@ +/* Test of isnand() substitute. + Copyright (C) 2007-2008 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 <http://www.gnu.org/licenses/>. */ + +/* Written by Bruno Haible <bruno@clisp.org>, 2007. */ + +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> + +#include "nan.h" + +#define ASSERT(expr) \ + do \ + { \ + if (!(expr)) \ + { \ + fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \ + fflush (stderr); \ + abort (); \ + } \ + } \ + while (0) + +int +main () +{ + /* Finite values. */ + ASSERT (!isnand (3.141)); + ASSERT (!isnand (3.141e30)); + ASSERT (!isnand (3.141e-30)); + ASSERT (!isnand (-2.718)); + ASSERT (!isnand (-2.718e30)); + ASSERT (!isnand (-2.718e-30)); + ASSERT (!isnand (0.0)); + ASSERT (!isnand (-0.0)); + /* Infinite values. */ + ASSERT (!isnand (1.0 / 0.0)); + ASSERT (!isnand (-1.0 / 0.0)); + /* Quiet NaN. */ + ASSERT (isnand (NaNd ())); +#if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT + /* Signalling NaN. */ + { + #define NWORDS \ + ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) + typedef union { double value; unsigned int word[NWORDS]; } memory_double; + memory_double m; + m.value = NaNd (); +# if DBL_EXPBIT0_BIT > 0 + m.word[DBL_EXPBIT0_WORD] ^= (unsigned int) 1 << (DBL_EXPBIT0_BIT - 1); +# else + m.word[DBL_EXPBIT0_WORD + (DBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)] + ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1); +# endif + m.word[DBL_EXPBIT0_WORD + (DBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)] + |= (unsigned int) 1 << DBL_EXPBIT0_BIT; + ASSERT (isnand (m.value)); + } +#endif + return 0; +}