summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2007-02-25 02:35:37 +0000
committerBruno Haible <bruno@clisp.org>2007-02-25 02:35:37 +0000
commit92765dd77a04d405b6521790e659e2319c309aeb (patch)
tree736bb3c56b7ce1bc107629cb2a021b5f1a70c4c8
parentce30cc7716b6d57bcfd7fe2f7485baa0df99b091 (diff)
downloadgnulib-92765dd77a04d405b6521790e659e2319c309aeb.tar.gz
Merge isnan and isnanl into a single source file.
-rw-r--r--ChangeLog7
-rw-r--r--lib/isnan.c49
-rw-r--r--lib/isnanl.c45
-rw-r--r--modules/isnanl-nolibm1
4 files changed, 46 insertions, 56 deletions
diff --git a/ChangeLog b/ChangeLog
index 20883883ed..14fedc7dbc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2007-02-24 Bruno Haible <bruno@clisp.org>
+
+ * lib/isnan.c: Support the 'long double' case if USE_LONG_DOUBLE is
+ defined.
+ * lib/isnanl.c: Remove all code. Just include isnan.c.
+ * modules/isnanl-nolibm (Files): Add lib/isnan.c.
+
2007-02-25 Jim Meyering <jim@meyering.net>
Avoid conflicting types for 'unsetenv' on FreeBSD.
diff --git a/lib/isnan.c b/lib/isnan.c
index efcef440be..ce9e8ea78d 100644
--- a/lib/isnan.c
+++ b/lib/isnan.c
@@ -22,32 +22,55 @@
#include <float.h>
#include <string.h>
-#define DBL_EXP_MASK ((DBL_MAX_EXP - DBL_MIN_EXP) | 7)
+#ifdef USE_LONG_DOUBLE
+# define FUNC rpl_isnanl
+# define DOUBLE long double
+# define MAX_EXP LDBL_MAX_EXP
+# define MIN_EXP LDBL_MIN_EXP
+# if defined LDBL_EXPBIT0_WORD && defined LDBL_EXPBIT0_BIT
+# define KNOWN_EXPBIT0_LOCATION
+# define EXPBIT0_WORD LDBL_EXPBIT0_WORD
+# define EXPBIT0_BIT LDBL_EXPBIT0_BIT
+# endif
+# define L_(literal) literal##L
+#else
+# define FUNC rpl_isnan
+# define DOUBLE double
+# define MAX_EXP DBL_MAX_EXP
+# define MIN_EXP DBL_MIN_EXP
+# if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
+# define KNOWN_EXPBIT0_LOCATION
+# define EXPBIT0_WORD DBL_EXPBIT0_WORD
+# define EXPBIT0_BIT DBL_EXPBIT0_BIT
+# endif
+# define L_(literal) literal
+#endif
+
+#define EXP_MASK ((MAX_EXP - MIN_EXP) | 7)
#define NWORDS \
- ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
-typedef union { double value; unsigned int word[NWORDS]; } memory_double;
+ ((sizeof (DOUBLE) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
+typedef union { DOUBLE value; unsigned int word[NWORDS]; } memory_double;
int
-rpl_isnan (double x)
+FUNC (DOUBLE x)
{
-#if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
+#ifdef KNOWN_EXPBIT0_LOCATION
/* Be careful to not do any floating-point operation on x, such as x == x,
because x may be a signaling NaN. */
- static memory_double nan = { 0.0 / 0.0 };
- static double plus_inf = 1.0 / 0.0;
- static double minus_inf = -1.0 / 0.0;
+ static memory_double nan = { L_(0.0) / L_(0.0) };
+ static DOUBLE plus_inf = L_(1.0) / L_(0.0);
+ static DOUBLE minus_inf = -L_(1.0) / L_(0.0);
memory_double m;
/* A NaN can be recognized through its exponent. But exclude +Infinity and
-Infinity, which have the same exponent. */
m.value = x;
- if ((((m.word[DBL_EXPBIT0_WORD] >> DBL_EXPBIT0_BIT)
- ^ (nan.word[DBL_EXPBIT0_WORD] >> DBL_EXPBIT0_BIT))
- & DBL_EXP_MASK)
+ if (((m.word[EXPBIT0_WORD] ^ nan.word[EXPBIT0_WORD])
+ & (EXP_MASK << EXPBIT0_BIT))
== 0)
- return (memcmp (&m.value, &plus_inf, sizeof (double)) != 0
- && memcmp (&m.value, &minus_inf, sizeof (double)) != 0);
+ return (memcmp (&m.value, &plus_inf, sizeof (DOUBLE)) != 0
+ && memcmp (&m.value, &minus_inf, sizeof (DOUBLE)) != 0);
else
return 0;
#else
diff --git a/lib/isnanl.c b/lib/isnanl.c
index 0412c5540e..9d0c98a59e 100644
--- a/lib/isnanl.c
+++ b/lib/isnanl.c
@@ -17,46 +17,5 @@
/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
-#include <config.h>
-
-#include <float.h>
-#include <string.h>
-
-#define LDBL_EXP_MASK ((LDBL_MAX_EXP - LDBL_MIN_EXP) | 7)
-
-#define NWORDS \
- ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
-typedef union { long double value; unsigned int word[NWORDS]; }
- memory_long_double;
-
-int
-rpl_isnanl (long double x)
-{
-#if defined LDBL_EXPBIT0_WORD && defined LDBL_EXPBIT0_BIT
- /* Be careful to not do any floating-point operation on x, such as x == x,
- because x may be a signalling NaN. */
- static memory_long_double nan = { 0.0L / 0.0L };
- static long double plus_inf = 1.0L / 0.0L;
- static long double minus_inf = -1.0L / 0.0L;
- memory_long_double m;
-
- /* A NaN can be recognized through its exponent. But exclude +Infinity and
- -Infinity, which have the same exponent. */
- m.value = x;
- if ((((m.word[LDBL_EXPBIT0_WORD] >> LDBL_EXPBIT0_BIT)
- ^ (nan.word[LDBL_EXPBIT0_WORD] >> LDBL_EXPBIT0_BIT))
- & LDBL_EXP_MASK)
- == 0)
- return (memcmp (&m.value, &plus_inf, sizeof (long double)) != 0
- && memcmp (&m.value, &minus_inf, sizeof (long double)) != 0);
- else
- return 0;
-#else
- /* The configuration did not find sufficient information. Give up about
- the signaling NaNs, handle only the quiet NaNs. */
- if (x == x)
- return 0;
- else
- return 1;
-#endif
-}
+#define USE_LONG_DOUBLE
+#include "isnan.c"
diff --git a/modules/isnanl-nolibm b/modules/isnanl-nolibm
index 2833ddc272..7cefd4a31a 100644
--- a/modules/isnanl-nolibm
+++ b/modules/isnanl-nolibm
@@ -4,6 +4,7 @@ isnanl() function: test for NaN, without requiring libm.
Files:
lib/isnanl.h
lib/isnanl.c
+lib/isnan.c
m4/isnanl.m4
m4/longdouble.m4