diff options
-rw-r--r-- | ChangeLog | 25 | ||||
-rw-r--r-- | lib/atanl.c | 7 | ||||
-rw-r--r-- | lib/cosl.c | 9 | ||||
-rw-r--r-- | lib/ldexpl.c | 3 | ||||
-rw-r--r-- | lib/logl.c | 11 | ||||
-rw-r--r-- | lib/sinl.c | 9 | ||||
-rw-r--r-- | lib/sqrtl.c | 9 | ||||
-rw-r--r-- | lib/tanl.c | 9 | ||||
-rw-r--r-- | lib/trigl.c | 2 |
9 files changed, 69 insertions, 15 deletions
@@ -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]; |