From: Bruno Haible Date: Mon, 26 Mar 2007 22:26:05 +0000 (+0000) Subject: Better support of signalling NaNs. X-Git-Tag: cvs-readonly~655 X-Git-Url: http://erislabs.org.uk/gitweb/?a=commitdiff_plain;h=55eed6bbc87934f2db04981e6f0f1773ff77974f;p=gnulib.git Better support of signalling NaNs. --- diff --git a/ChangeLog b/ChangeLog index ae0f03e68..c75a53077 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2007-03-26 Bruno Haible + + 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 * m4/vasnprintf.m4 (gl_PREREQ_VASNPRINTF_DIRECTIVE_A): Fix diff --git a/lib/atanl.c b/lib/atanl.c index 16c8dc12b..3f8bda4c6 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 3c28f77c6..8a9cb56c0 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 6ad886a42..f85847b24 100644 --- a/lib/ldexpl.c +++ b/lib/ldexpl.c @@ -25,6 +25,7 @@ #include #include +#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 dc75a8fd7..16053cf3f 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 02c70354f..2c9068f61 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 3702f027e..bf1b2d5fa 100644 --- a/lib/sqrtl.c +++ b/lib/sqrtl.c @@ -25,6 +25,7 @@ #include #include +#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 d173d6bd5..64a84b86f 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 a34e98f49..c82b509a3 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];