From fc11af0a623e95f1c0dc57aa56c134e380752770 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sat, 12 Jul 2008 10:45:22 -0700 Subject: [PATCH] Add isnand module. --- ChangeLog | 21 +++++++++++++ MODULES.html.sh | 1 + lib/isnand.h | 33 ++++++++++++++++++++ m4/isnand.m4 | 76 ++++++++++++++++++++++++++++++++++++++++----- modules/isnand | 30 ++++++++++++++++++ modules/isnand-nolibm-tests | 1 + modules/isnand-tests | 15 +++++++++ tests/test-isnand-nolibm.c | 58 +--------------------------------- tests/test-isnand.c | 22 +++++++++++++ tests/test-isnand.h | 74 +++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 266 insertions(+), 65 deletions(-) create mode 100644 lib/isnand.h create mode 100644 modules/isnand create mode 100644 modules/isnand-tests create mode 100644 tests/test-isnand.c create mode 100644 tests/test-isnand.h diff --git a/ChangeLog b/ChangeLog index b68b33f4e..3a539d02f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,26 @@ 2008-07-10 Ben Pfaff + 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 + * lib/isnanf.h: Rename lib/isnanf-nolibm.h. * lib/isnand.h: Rename lib/isnand-nolibm.h. * tests/test-isnanf.c: Rename tests/test-isnanf-nolibm.c. diff --git a/MODULES.html.sh b/MODULES.html.sh index 8f3aa4f5b..6990731d6 100755 --- a/MODULES.html.sh +++ b/MODULES.html.sh @@ -2000,6 +2000,7 @@ func_all_modules () 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 diff --git a/lib/isnand.h b/lib/isnand.h new file mode 100644 index 000000000..d809aaa68 --- /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 . */ + +#if HAVE_ISNAND +/* Get declaration of isnan macro. */ +# include +# 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 diff --git a/m4/isnand.m4 b/m4/isnand.m4 index 7783b424e..083051ba9 100644 --- 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 + #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 @@ AC_DEFUN([gl_FUNC_ISNAND_NO_LIBM], [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], diff --git a/modules/isnand b/modules/isnand new file mode 100644 index 000000000..ab6cda588 --- /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 + diff --git a/modules/isnand-nolibm-tests b/modules/isnand-nolibm-tests index 2283fbae0..63273349b 100644 --- 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: diff --git a/modules/isnand-tests b/modules/isnand-tests new file mode 100644 index 000000000..8d406feb7 --- /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@ + diff --git a/tests/test-isnand-nolibm.c b/tests/test-isnand-nolibm.c index 391871f95..fd739ca39 100644 --- 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 . */ -/* Written by Bruno Haible , 2007. */ - #include #include "isnand-nolibm.h" -#include -#include -#include - -#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; -} diff --git a/tests/test-isnand.c b/tests/test-isnand.c new file mode 100644 index 000000000..fc754d33d --- /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 . */ + +#include + +#include "isnand.h" + +#include "test-isnand.h" + diff --git a/tests/test-isnand.h b/tests/test-isnand.h new file mode 100644 index 000000000..cf8cb5d4b --- /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 . */ + +/* Written by Bruno Haible , 2007. */ + +#include +#include +#include + +#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; +} -- 2.11.0