summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog25
-rw-r--r--lib/atanl.c7
-rw-r--r--lib/cosl.c9
-rw-r--r--lib/ldexpl.c3
-rw-r--r--lib/logl.c11
-rw-r--r--lib/sinl.c9
-rw-r--r--lib/sqrtl.c9
-rw-r--r--lib/tanl.c9
-rw-r--r--lib/trigl.c2
9 files changed, 69 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index ae0f03e68f..c75a530774 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+2007-03-26 Bruno Haible <bruno@clisp.org>
+
+ Better support of signalling NaNs.
+ * lib/atanl.c: Include isnanl.h.
+ (atanl): Perform test for NaN at the beginning of the function and
+ through a call to isnanl.
+ * lib/cosl.c: Include isnanl.h.
+ (cosl): Perform test for NaN at the beginning of the function and
+ through a call to isnanl.
+ * lib/ldexpl.c: Include isnanl.h.
+ (ldexpl): Perform test for NaN through a call to isnanl.
+ * lib/logl.c: Include isnanl.h.
+ (logl): Perform test for NaN at the beginning of the function and
+ through a call to isnanl.
+ * lib/sinl.c: Include isnanl.h.
+ (sinl): Perform test for NaN at the beginning of the function and
+ through a call to isnanl.
+ * lib/sqrtl.c: Include isnanl.h.
+ (sqrtl): Perform test for NaN at the beginning of the function and
+ through a call to isnanl.
+ * lib/tanl.c: Include isnanl.h.
+ (tanl): Perform test for NaN at the beginning of the function and
+ through a call to isnanl.
+ * lib/trigl.c (ieee754_rem_pio2l): Remove test for NaN.
+
2007-03-26 Eric Blake <ebb9@byu.net>
* m4/vasnprintf.m4 (gl_PREREQ_VASNPRINTF_DIRECTIVE_A): Fix
diff --git a/lib/atanl.c b/lib/atanl.c
index 16c8dc12bf..3f8bda4c62 100644
--- a/lib/atanl.c
+++ b/lib/atanl.c
@@ -64,6 +64,7 @@
*
*/
+#include "isnanl.h"
/* arctan(k/8), k = 0, ..., 82 */
static const long double atantbl[84] = {
@@ -178,12 +179,12 @@ atanl (long double x)
int k, sign;
long double t, u, p, q;
- sign = x < 0.0;
-
/* Check for zero or NaN. */
- if (x != x || x == 0.0)
+ if (isnanl (x) || x == 0.0)
return x + x;
+ sign = x < 0.0;
+
if (x + x == x)
{
/* Infinity. */
diff --git a/lib/cosl.c b/lib/cosl.c
index 3c28f77c6d..8a9cb56c01 100644
--- a/lib/cosl.c
+++ b/lib/cosl.c
@@ -54,19 +54,24 @@
#include "trigl.c"
#include "sincosl.c"
#endif
+#include "isnanl.h"
long double cosl(long double x)
{
long double y[2],z=0.0L;
int n;
+ /* cosl(NaN) is NaN */
+ if (isnanl (x))
+ return x;
+
/* |x| ~< pi/4 */
if(x >= -0.7853981633974483096156608458198757210492 &&
x <= 0.7853981633974483096156608458198757210492)
return kernel_cosl(x, z);
- /* sinl(Inf or NaN) is NaN, sinl(0) is 0 */
- else if ((x + x == x && x != 0.0) || x != x)
+ /* cosl(Inf) is NaN, cosl(0) is 1 */
+ else if (x + x == x && x != 0.0)
return x-x; /* NaN */
/* argument reduction needed */
diff --git a/lib/ldexpl.c b/lib/ldexpl.c
index 6ad886a427..f85847b24e 100644
--- a/lib/ldexpl.c
+++ b/lib/ldexpl.c
@@ -25,6 +25,7 @@
#include <math.h>
#include <float.h>
+#include "isnanl.h"
long double
ldexpl(long double x, int exp)
@@ -33,7 +34,7 @@ ldexpl(long double x, int exp)
int bit;
/* Check for zero, nan and infinity. */
- if (x != x || x + x == x )
+ if (isnanl (x) || x + x == x)
return x;
if (exp < 0)
diff --git a/lib/logl.c b/lib/logl.c
index dc75a8fd72..16053cf3f3 100644
--- a/lib/logl.c
+++ b/lib/logl.c
@@ -64,6 +64,8 @@
*
*/
+#include "isnanl.h"
+
/* log(1+x) = x - .5 x^2 + x^3 l(x)
-.0078125 <= x <= +.0078125
peak relative error 1.2e-37 */
@@ -196,6 +198,11 @@ logl(long double x)
/* Check for IEEE special cases. */
+ /* log(NaN) = NaN. */
+ if (isnanl (x))
+ {
+ return x;
+ }
/* log(0) = -infinity. */
if (x == 0.0L)
{
@@ -206,8 +213,8 @@ logl(long double x)
{
return (x - x) / ZERO;
}
- /* log (infinity or NaN) */
- if (x + x == x || x != x)
+ /* log (infinity) */
+ if (x + x == x)
{
return x + x;
}
diff --git a/lib/sinl.c b/lib/sinl.c
index 02c70354f5..2c9068f619 100644
--- a/lib/sinl.c
+++ b/lib/sinl.c
@@ -52,6 +52,7 @@
#include "trigl.h"
#include "trigl.c"
#include "sincosl.c"
+#include "isnanl.h"
long double
sinl (long double x)
@@ -59,13 +60,17 @@ sinl (long double x)
long double y[2], z = 0.0L;
int n;
+ /* sinl(NaN) is NaN */
+ if (isnanl (x))
+ return x;
+
/* |x| ~< pi/4 */
if (x >= -0.7853981633974483096156608458198757210492 &&
x <= 0.7853981633974483096156608458198757210492)
return kernel_sinl (x, z, 0);
- /* sinl(Inf or NaN) is NaN, sinl(0) is 0 */
- else if (x + x == x || x != x)
+ /* sinl(Inf) is NaN, sinl(0) is 0 */
+ else if (x + x == x)
return x - x; /* NaN */
/* argument reduction needed */
diff --git a/lib/sqrtl.c b/lib/sqrtl.c
index 3702f027ef..bf1b2d5faa 100644
--- a/lib/sqrtl.c
+++ b/lib/sqrtl.c
@@ -25,6 +25,7 @@
#include <math.h>
#include <float.h>
+#include "isnanl.h"
/* A simple Newton-Raphson method. */
long double
@@ -33,12 +34,16 @@ sqrtl(long double x)
long double delta, y;
int exponent;
+ /* Check for NaN */
+ if (isnanl (x))
+ return x;
+
/* Check for negative numbers */
if (x < 0.0L)
return (long double) sqrt(-1);
- /* Check for zero, NANs and infinites */
- if (x + x == x || x != x)
+ /* Check for zero and infinites */
+ if (x + x == x)
return x;
frexpl (x, &exponent);
diff --git a/lib/tanl.c b/lib/tanl.c
index d173d6bd54..64a84b86f8 100644
--- a/lib/tanl.c
+++ b/lib/tanl.c
@@ -55,6 +55,7 @@
#include "trigl.c"
#endif
#endif
+#include "isnanl.h"
/*
* ====================================================
@@ -191,13 +192,17 @@ tanl (long double x)
long double y[2], z = 0.0L;
int n;
+ /* tanl(NaN) is NaN */
+ if (isnanl (x))
+ return x;
+
/* |x| ~< pi/4 */
if (x >= -0.7853981633974483096156608458198757210492 &&
x <= 0.7853981633974483096156608458198757210492)
return kernel_tanl (x, z, 1);
- /* tanl(Inf or NaN) is NaN, tanl(0) is 0 */
- else if (x + x == x || x != x)
+ /* tanl(Inf) is NaN, tanl(0) is 0 */
+ else if (x + x == x)
return x - x; /* NaN */
/* argument reduction needed */
diff --git a/lib/trigl.c b/lib/trigl.c
index a34e98f493..c82b509a3b 100644
--- a/lib/trigl.c
+++ b/lib/trigl.c
@@ -233,7 +233,7 @@ ieee754_rem_pio2l (long double x, long double *y)
return -1;
}
- if (x + x == x || x != x) /* x is +=oo or NaN */
+ if (x + x == x) /* x is ±oo */
{
y[0] = x - x;
y[1] = y[0];