summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog21
-rwxr-xr-xMODULES.html.sh1
-rw-r--r--lib/isnand.h33
-rw-r--r--m4/isnand.m476
-rw-r--r--modules/isnand30
-rw-r--r--modules/isnand-nolibm-tests1
-rw-r--r--modules/isnand-tests15
-rw-r--r--tests/test-isnand-nolibm.c58
-rw-r--r--tests/test-isnand.c22
-rw-r--r--tests/test-isnand.h74
10 files changed, 266 insertions, 65 deletions
diff --git a/ChangeLog b/ChangeLog
index b68b33f4ec..3a539d02f4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,26 @@
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.
* 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 8f3aa4f5bf..6990731d6b 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 0000000000..d809aaa688
--- /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
diff --git a/m4/isnand.m4 b/m4/isnand.m4
index 7783b424e6..083051ba9f 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 <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 @@ 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 0000000000..ab6cda588a
--- /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 2283fbae07..63273349b4 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 0000000000..8d406feb7f
--- /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 391871f956..fd739ca39f 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 <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;
-}
diff --git a/tests/test-isnand.c b/tests/test-isnand.c
new file mode 100644
index 0000000000..fc754d33de
--- /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"
+
diff --git a/tests/test-isnand.h b/tests/test-isnand.h
new file mode 100644
index 0000000000..cf8cb5d4ba
--- /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;
+}