about summary refs log tree commit diff
path: root/math
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2013-12-04 14:39:37 +0000
committerJoseph Myers <joseph@codesourcery.com>2013-12-04 14:39:37 +0000
commit699ff83712b5796ac50ed332d9dad55d38450e81 (patch)
tree8e2470bbcf5d1d18813aa9d063771b083c8667af /math
parent5b118558f9fb0620508d51c34c2cb5ba4f1f01c2 (diff)
downloadglibc-699ff83712b5796ac50ed332d9dad55d38450e81.tar.gz
glibc-699ff83712b5796ac50ed332d9dad55d38450e81.tar.xz
glibc-699ff83712b5796ac50ed332d9dad55d38450e81.zip
Fix Bessel function error handling (bug 6807, bug 15901).
Diffstat (limited to 'math')
-rw-r--r--math/libm-test.inc66
-rw-r--r--math/w_j0.c7
-rw-r--r--math/w_j0f.c7
-rw-r--r--math/w_j0l.c7
-rw-r--r--math/w_j1.c7
-rw-r--r--math/w_j1f.c7
-rw-r--r--math/w_j1l.c7
-rw-r--r--math/w_jn.c7
-rw-r--r--math/w_jnf.c7
9 files changed, 95 insertions, 27 deletions
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 2e3e684ca3..a4b2d51ef9 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -14278,9 +14278,11 @@ trunc_test (void)
 static const struct test_f_f_data y0_test_data[] =
   {
     /* y0 is the Bessel function of the second kind of order 0 */
-    TEST_f_f (y0, -1.0, minus_infty, INVALID_EXCEPTION|ERRNO_EDOM),
-    TEST_f_f (y0, -max_value, minus_infty, INVALID_EXCEPTION|ERRNO_EDOM),
-    TEST_f_f (y0, 0.0, minus_infty),
+    TEST_f_f (y0, -1.0, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_f_f (y0, -max_value, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_f_f (y0, minus_infty, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_f_f (y0, 0.0, minus_infty, DIVIDE_BY_ZERO_EXCEPTION|ERRNO_ERANGE),
+    TEST_f_f (y0, -0.0, minus_infty, DIVIDE_BY_ZERO_EXCEPTION|ERRNO_ERANGE),
     TEST_f_f (y0, qnan_value, qnan_value, NO_INEXACT_EXCEPTION),
     TEST_f_f (y0, plus_infty, 0),
 
@@ -14329,9 +14331,11 @@ y0_test (void)
 static const struct test_f_f_data y1_test_data[] =
   {
     /* y1 is the Bessel function of the second kind of order 1 */
-    TEST_f_f (y1, -1.0, minus_infty, INVALID_EXCEPTION|ERRNO_EDOM),
-    TEST_f_f (y1, -max_value, minus_infty, INVALID_EXCEPTION|ERRNO_EDOM),
-    TEST_f_f (y1, 0.0, minus_infty),
+    TEST_f_f (y1, -1.0, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_f_f (y1, -max_value, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_f_f (y1, minus_infty, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_f_f (y1, 0.0, minus_infty, DIVIDE_BY_ZERO_EXCEPTION|ERRNO_ERANGE),
+    TEST_f_f (y1, -0.0, minus_infty, DIVIDE_BY_ZERO_EXCEPTION|ERRNO_ERANGE),
     TEST_f_f (y1, plus_infty, 0),
     TEST_f_f (y1, qnan_value, qnan_value, NO_INEXACT_EXCEPTION),
 
@@ -14381,9 +14385,11 @@ static const struct test_if_f_data yn_test_data[] =
   {
     /* yn is the Bessel function of the second kind of order n */
     /* yn (0, x) == y0 (x)  */
-    TEST_if_f (yn, 0, -1.0, minus_infty, INVALID_EXCEPTION|ERRNO_EDOM),
-    TEST_if_f (yn, 0, -max_value, minus_infty, INVALID_EXCEPTION|ERRNO_EDOM),
-    TEST_if_f (yn, 0, 0.0, minus_infty),
+    TEST_if_f (yn, 0, -1.0, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_if_f (yn, 0, -max_value, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_if_f (yn, 0, minus_infty, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_if_f (yn, 0, 0.0, minus_infty, DIVIDE_BY_ZERO_EXCEPTION|ERRNO_ERANGE),
+    TEST_if_f (yn, 0, -0.0, minus_infty, DIVIDE_BY_ZERO_EXCEPTION|ERRNO_ERANGE),
     TEST_if_f (yn, 0, qnan_value, qnan_value, NO_INEXACT_EXCEPTION),
     TEST_if_f (yn, 0, plus_infty, 0),
 
@@ -14396,8 +14402,11 @@ static const struct test_if_f_data yn_test_data[] =
     TEST_if_f (yn, 0, 10.0, 0.0556711672835993914244598774101900481L),
 
     /* yn (1, x) == y1 (x)  */
-    TEST_if_f (yn, 1, -1.0, minus_infty, INVALID_EXCEPTION|ERRNO_EDOM),
-    TEST_if_f (yn, 1, 0.0, minus_infty),
+    TEST_if_f (yn, 1, -1.0, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_if_f (yn, 1, -max_value, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_if_f (yn, 1, minus_infty, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_if_f (yn, 1, 0.0, minus_infty, DIVIDE_BY_ZERO_EXCEPTION|ERRNO_ERANGE),
+    TEST_if_f (yn, 1, -0.0, minus_infty, DIVIDE_BY_ZERO_EXCEPTION|ERRNO_ERANGE),
     TEST_if_f (yn, 1, plus_infty, 0),
     TEST_if_f (yn, 1, qnan_value, qnan_value, NO_INEXACT_EXCEPTION),
 
@@ -14409,7 +14418,40 @@ static const struct test_if_f_data yn_test_data[] =
     TEST_if_f (yn, 1, 8.0, -0.158060461731247494255555266187483550L),
     TEST_if_f (yn, 1, 10.0, 0.249015424206953883923283474663222803L),
 
+    /* yn (-1, x) == -y1 (x).  */
+    TEST_if_f (yn, -1, -1.0, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_if_f (yn, -1, -max_value, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_if_f (yn, -1, minus_infty, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_if_f (yn, -1, 0.0, plus_infty, DIVIDE_BY_ZERO_EXCEPTION|ERRNO_ERANGE),
+    TEST_if_f (yn, -1, -0.0, plus_infty, DIVIDE_BY_ZERO_EXCEPTION|ERRNO_ERANGE),
+    TEST_if_f (yn, -1, plus_infty, minus_zero),
+    TEST_if_f (yn, -1, qnan_value, qnan_value, NO_INEXACT_EXCEPTION),
+    TEST_if_f (yn, -1, 1.0, 0.781212821300288716547150000047964821L),
+
+    /* yn (2, x).  */
+    TEST_if_f (yn, 2, -1.0, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_if_f (yn, 2, -max_value, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_if_f (yn, 2, minus_infty, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_if_f (yn, 2, 0.0, minus_infty, DIVIDE_BY_ZERO_EXCEPTION|ERRNO_ERANGE),
+    TEST_if_f (yn, 2, -0.0, minus_infty, DIVIDE_BY_ZERO_EXCEPTION|ERRNO_ERANGE),
+    TEST_if_f (yn, 2, plus_infty, 0),
+    TEST_if_f (yn, 2, qnan_value, qnan_value, NO_INEXACT_EXCEPTION),
+
+    /* yn (-2, x) == yn (2, x).  */
+    TEST_if_f (yn, -2, -1.0, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_if_f (yn, -2, -max_value, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_if_f (yn, -2, minus_infty, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_if_f (yn, -2, 0.0, minus_infty, DIVIDE_BY_ZERO_EXCEPTION|ERRNO_ERANGE),
+    TEST_if_f (yn, -2, -0.0, minus_infty, DIVIDE_BY_ZERO_EXCEPTION|ERRNO_ERANGE),
+    TEST_if_f (yn, -2, plus_infty, 0),
+    TEST_if_f (yn, -2, qnan_value, qnan_value, NO_INEXACT_EXCEPTION),
+
     /* yn (3, x)  */
+    TEST_if_f (yn, 3, -1.0, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_if_f (yn, 3, -max_value, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_if_f (yn, 3, minus_infty, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_if_f (yn, 3, 0.0, minus_infty, DIVIDE_BY_ZERO_EXCEPTION|ERRNO_ERANGE),
+    TEST_if_f (yn, 3, -0.0, minus_infty, DIVIDE_BY_ZERO_EXCEPTION|ERRNO_ERANGE),
     TEST_if_f (yn, 3, plus_infty, 0),
     TEST_if_f (yn, 3, qnan_value, qnan_value, NO_INEXACT_EXCEPTION),
 
@@ -14429,6 +14471,8 @@ static const struct test_if_f_data yn_test_data[] =
     TEST_if_f (yn, 10, 2.0, -129184.542208039282635913145923304214L),
     TEST_if_f (yn, 10, 10.0, -0.359814152183402722051986577343560609L),
 
+    TEST_if_f (yn, -10, 1.0, -121618014.278689189288130426667971145L),
+
     /* Check whether yn returns correct value for LDBL_MIN, DBL_MIN,
        and FLT_MIN.  See Bug 14173.  */
     TEST_if_f (yn, 10, min_value, minus_infty, OVERFLOW_EXCEPTION|ERRNO_ERANGE),
diff --git a/math/w_j0.c b/math/w_j0.c
index 53671c3306..0849abbc35 100644
--- a/math/w_j0.c
+++ b/math/w_j0.c
@@ -51,8 +51,11 @@ y0 (double x)
 	  return __kernel_standard (x, x, 9);
 	}
       else if (x == 0.0)
-	/* d = -one/(x-x) */
-	return __kernel_standard (x, x, 8);
+	{
+	  /* d = -one/(x-x) */
+	  feraiseexcept (FE_DIVBYZERO);
+	  return __kernel_standard (x, x, 8);
+	}
       else if (_LIB_VERSION != _POSIX_)
 	/* y0(x>X_TLOSS) */
 	return __kernel_standard (x, x, 35);
diff --git a/math/w_j0f.c b/math/w_j0f.c
index c9a6c53fff..ef309d2092 100644
--- a/math/w_j0f.c
+++ b/math/w_j0f.c
@@ -49,8 +49,11 @@ y0f (float x)
 	  return __kernel_standard_f (x, x, 109);
 	}
       else if (x == 0.0f)
-	/* d = -one/(x-x) */
-	return __kernel_standard_f (x, x, 108);
+	{
+	  /* d = -one/(x-x) */
+	  feraiseexcept (FE_DIVBYZERO);
+	  return __kernel_standard_f (x, x, 108);
+	}
       else if (_LIB_VERSION != _POSIX_)
 	/* y0(x>X_TLOSS) */
 	return __kernel_standard_f (x, x, 135);
diff --git a/math/w_j0l.c b/math/w_j0l.c
index 717253c001..01cd91cdb7 100644
--- a/math/w_j0l.c
+++ b/math/w_j0l.c
@@ -49,8 +49,11 @@ __y0l (long double x)
 	  return __kernel_standard_l (x, x, 209);
 	}
       else if (x == 0.0L)
-	/* d = -one/(x-x) */
-	return __kernel_standard_l (x, x, 208);
+	{
+	  /* d = -one/(x-x) */
+	  feraiseexcept (FE_DIVBYZERO);
+	  return __kernel_standard_l (x, x, 208);
+	}
       else if (_LIB_VERSION != _POSIX_)
 	/* y0(x>X_TLOSS) */
 	return __kernel_standard_l (x, x, 235);
diff --git a/math/w_j1.c b/math/w_j1.c
index 743c940b14..a9fb7aebbe 100644
--- a/math/w_j1.c
+++ b/math/w_j1.c
@@ -51,8 +51,11 @@ y1 (double x)
 	  return __kernel_standard (x, x, 11);
 	}
       else if (x == 0.0)
-	/* d = -one/(x-x) */
-	return __kernel_standard (x, x, 10);
+	{
+	  /* d = -one/(x-x) */
+	  feraiseexcept (FE_DIVBYZERO);
+	  return __kernel_standard (x, x, 10);
+	}
       else if (_LIB_VERSION != _POSIX_)
 	/* y1(x>X_TLOSS) */
 	return __kernel_standard (x, x, 37);
diff --git a/math/w_j1f.c b/math/w_j1f.c
index bf7deb09f7..f70913d5ae 100644
--- a/math/w_j1f.c
+++ b/math/w_j1f.c
@@ -49,8 +49,11 @@ y1f (float x)
 	  return __kernel_standard_f (x, x, 111);
 	}
       else if (x == 0.0f)
-	/* d = -one/(x-x) */
-	return __kernel_standard_f (x, x, 110);
+	{
+	  /* d = -one/(x-x) */
+	  feraiseexcept (FE_DIVBYZERO);
+	  return __kernel_standard_f (x, x, 110);
+	}
       else if (_LIB_VERSION != _POSIX_)
 	/* y1(x>X_TLOSS) */
 	return __kernel_standard_f (x, x, 137);
diff --git a/math/w_j1l.c b/math/w_j1l.c
index c4f8111ca2..e4242ec218 100644
--- a/math/w_j1l.c
+++ b/math/w_j1l.c
@@ -49,8 +49,11 @@ __y1l (long double x)
 	  return __kernel_standard_l (x, x, 211);
 	}
       else if (x == 0.0L)
-	/* d = -one/(x-x) */
-	return __kernel_standard_l (x, x, 210);
+	{
+	  /* d = -one/(x-x) */
+	  feraiseexcept (FE_DIVBYZERO);
+	  return __kernel_standard_l (x, x, 210);
+	}
       else if (_LIB_VERSION != _POSIX_)
 	/* y1(x>X_TLOSS) */
 	return __kernel_standard_l (x, x, 237);
diff --git a/math/w_jn.c b/math/w_jn.c
index e2e69b4239..e9179835ba 100644
--- a/math/w_jn.c
+++ b/math/w_jn.c
@@ -51,8 +51,11 @@ yn (int n, double x)
 	  return __kernel_standard (n, x, 13);
 	}
       else if (x == 0.0)
-	/* d = -one/(x-x) */
-	return __kernel_standard (n, x, 12);
+	{
+	  /* d = -one/(x-x) */
+	  feraiseexcept (FE_DIVBYZERO);
+	  return __kernel_standard (n, x, 12);
+	}
       else if (_LIB_VERSION != _POSIX_)
 	/* yn(n,x>X_TLOSS) */
 	return __kernel_standard (n, x, 39);
diff --git a/math/w_jnf.c b/math/w_jnf.c
index c9114e7b09..cb1aab8e73 100644
--- a/math/w_jnf.c
+++ b/math/w_jnf.c
@@ -49,8 +49,11 @@ ynf (int n, float x)
 	  return __kernel_standard_f (n, x, 113);
 	}
       else if (x == 0.0)
-	/* d = -one/(x-x) */
-	return __kernel_standard_f (n, x, 112);
+	{
+	  /* d = -one/(x-x) */
+	  feraiseexcept (FE_DIVBYZERO);
+	  return __kernel_standard_f (n, x, 112);
+	}
       else if (_LIB_VERSION != _POSIX_)
 	/* yn(n,x>X_TLOSS) */
 	return __kernel_standard_f (n, x, 139);