This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix Bessel function error handling (bug 6807, bug 15901)


Bugs 6807 and 15901 report problems with the handling of errors from
y0 / y1 / yn: negative arguments should, like other domain errors,
produce a NaN result, while 0 is a pole error, should produce an
ERANGE errno value with divide-by-zero exception and should produce an
infinity whose sign depends on the value of n in the case of yn.

This patch fixes those bugs in the way most consistent with the
surrounding code.  The wrapper functions are changed to raise
FE_DIVBYZERO explicitly, just as they raise FE_INVALID explicitly
(except for the ynl wrapper, which does things differently from all
the other wrappers for some reason) - maybe they should all change to
call the __ieee754_* functions first, like the __ynl wrapper does, but
that's a separate issue.  __kernel_standard is adjusted to produce the
appropriate errno values and returns - errno values and exception
structure are left unchanged in the deprecated matherr case as that
seems safest for this deprecated interface.  The underlying ynl
implementations are changed to produce the appropriate return and
exceptions for zero arguments, as required by the nature of that
wrapper.  (There may well be such bugs in other underlying
implementations that would only show up with -lieee - clearly we do
need tests of -ffinite-math-only and -lieee to test those function
variants better, although I also think -lieee, which uses
_LIB_VERSION, should be replaced by __*_noerrno function variants
enabled with -fno-math-errno.)

Tested x86_64 and x86 and ulps updated accordingly (for the new tests
of yn with negative n and finite arguments; such tests were previously
lacking).

2013-12-04  Joseph Myers  <joseph@codesourcery.com>

	[BZ #6807]
	[BZ #15901]
	* math/w_j0.c (y0): Raise FE_DIVBYZERO on zero argument.
	* math/w_j0f.c (y0f): Likewise.
	* math/w_j0l.c (__y0l): Likewise.
	* math/w_j1.c (y1): Likewise.
	* math/w_j1f.c (y1f): Likewise.
	* math/w_j1l.c (__y1l): Likewise
	* math/w_jn.c (yn): Likewise.
	* math/w_jnf.c (ynf): Likewise.
	* sysdeps/ieee754/k_standard.c (__kernel_standard): Use ERANGE for
	Bessel function pole errors in _POSIX_ mode.  Use NAN as return
	value for Bessel function domain errors outside _SVID_ mode.
	Adjust sign of return value for yn (negative integer, 0).
	* sysdeps/ieee754/ldbl-128/e_jnl.c (__ieee754_ynl): Use division
	by zero in return for negative x and set sign appropriately for
	negative n.
	* sysdeps/ieee754/ldbl-128ibm/e_jnl.c (__ieee754_ynl): Likewise.
	* sysdeps/ieee754/ldbl-96/e_jnl.c (__ieee754_ynl): Likewise.
	* math/libm-test.inc (y0_test_data): Add more tests and adjust
	expectations in error cases.
	(y1_test_data): Likewise.
	(yn_test_data): Likewise.
	* sysdeps/i386/fpu/libm-test-ulps: Update.
	* sysdeps/x86_64/fpu/libm-test-ulps: Likewise.

diff --git a/math/libm-test.inc b/math/libm-test.inc
index 2e3e684..a4b2d51 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 53671c3..0849abb 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 c9a6c53..ef309d2 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 717253c..01cd91c 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 743c940..a9fb7ae 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 bf7deb0..f70913d 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 c4f8111..e4242ec 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 e2e69b4..e917983 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 c9114e7..cb1aab8 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);
diff --git a/sysdeps/i386/fpu/libm-test-ulps b/sysdeps/i386/fpu/libm-test-ulps
index 4ed02a2..cf7c5e8 100644
--- a/sysdeps/i386/fpu/libm-test-ulps
+++ b/sysdeps/i386/fpu/libm-test-ulps
@@ -7563,6 +7563,9 @@ float: 2
 ifloat: 2
 
 # yn
+Test "yn (-10, 1.0)":
+float: 2
+ifloat: 2
 Test "yn (0, 0.125)":
 ildouble: 1
 ldouble: 1
diff --git a/sysdeps/ieee754/k_standard.c b/sysdeps/ieee754/k_standard.c
index 4a0d82d..5399c66 100644
--- a/sysdeps/ieee754/k_standard.c
+++ b/sysdeps/ieee754/k_standard.c
@@ -248,7 +248,7 @@ __kernel_standard(double x, double y, int type)
 		else
 		  exc.retval = -HUGE_VAL;
 		if (_LIB_VERSION == _POSIX_)
-		  __set_errno (EDOM);
+		  __set_errno (ERANGE);
 		else if (!matherr(&exc)) {
 		  if (_LIB_VERSION == _SVID_) {
 			(void) WRITE2("y0: DOMAIN error\n", 17);
@@ -265,7 +265,7 @@ __kernel_standard(double x, double y, int type)
 		if (_LIB_VERSION == _SVID_)
 		  exc.retval = -HUGE;
 		else
-		  exc.retval = -HUGE_VAL;
+		  exc.retval = NAN;
 		if (_LIB_VERSION == _POSIX_)
 		  __set_errno (EDOM);
 		else if (!matherr(&exc)) {
@@ -286,7 +286,7 @@ __kernel_standard(double x, double y, int type)
 		else
 		  exc.retval = -HUGE_VAL;
 		if (_LIB_VERSION == _POSIX_)
-		  __set_errno (EDOM);
+		  __set_errno (ERANGE);
 		else if (!matherr(&exc)) {
 		  if (_LIB_VERSION == _SVID_) {
 			(void) WRITE2("y1: DOMAIN error\n", 17);
@@ -303,7 +303,7 @@ __kernel_standard(double x, double y, int type)
 		if (_LIB_VERSION == _SVID_)
 		  exc.retval = -HUGE;
 		else
-		  exc.retval = -HUGE_VAL;
+		  exc.retval = NAN;
 		if (_LIB_VERSION == _POSIX_)
 		  __set_errno (EDOM);
 		else if (!matherr(&exc)) {
@@ -322,9 +322,11 @@ __kernel_standard(double x, double y, int type)
 		if (_LIB_VERSION == _SVID_)
 		  exc.retval = -HUGE;
 		else
-		  exc.retval = -HUGE_VAL;
+		  exc.retval = ((x < 0 && ((int) x & 1) != 0)
+				? HUGE_VAL
+				: -HUGE_VAL);
 		if (_LIB_VERSION == _POSIX_)
-		  __set_errno (EDOM);
+		  __set_errno (ERANGE);
 		else if (!matherr(&exc)) {
 		  if (_LIB_VERSION == _SVID_) {
 			(void) WRITE2("yn: DOMAIN error\n", 17);
@@ -341,7 +343,7 @@ __kernel_standard(double x, double y, int type)
 		if (_LIB_VERSION == _SVID_)
 		  exc.retval = -HUGE;
 		else
-		  exc.retval = -HUGE_VAL;
+		  exc.retval = NAN;
 		if (_LIB_VERSION == _POSIX_)
 		  __set_errno (EDOM);
 		else if (!matherr(&exc)) {
diff --git a/sysdeps/ieee754/ldbl-128/e_jnl.c b/sysdeps/ieee754/ldbl-128/e_jnl.c
index 70d5672..c2a4923 100644
--- a/sysdeps/ieee754/ldbl-128/e_jnl.c
+++ b/sysdeps/ieee754/ldbl-128/e_jnl.c
@@ -316,7 +316,7 @@ __ieee754_ynl (int n, long double x)
   if (x <= 0.0L)
     {
       if (x == 0.0L)
-	return -HUGE_VALL + x;
+	return ((n < 0 && (n & 1) != 0) ? 1.0L : -1.0L) / 0.0L;
       if (se & 0x80000000)
 	return zero / (zero * x);
     }
diff --git a/sysdeps/ieee754/ldbl-128ibm/e_jnl.c b/sysdeps/ieee754/ldbl-128ibm/e_jnl.c
index 817977d..6761a0d 100644
--- a/sysdeps/ieee754/ldbl-128ibm/e_jnl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/e_jnl.c
@@ -316,7 +316,7 @@ __ieee754_ynl (int n, long double x)
   if (x <= 0.0L)
     {
       if (x == 0.0L)
-	return -HUGE_VALL + x;
+	return ((n < 0 && (n & 1) != 0) ? 1.0L : -1.0L) / 0.0L;
       if (se & 0x80000000)
 	return zero / (zero * x);
     }
diff --git a/sysdeps/ieee754/ldbl-96/e_jnl.c b/sysdeps/ieee754/ldbl-96/e_jnl.c
index 58a9107..fa8e27e 100644
--- a/sysdeps/ieee754/ldbl-96/e_jnl.c
+++ b/sysdeps/ieee754/ldbl-96/e_jnl.c
@@ -302,7 +302,8 @@ __ieee754_ynl (int n, long double x)
   if (__builtin_expect ((ix == 0x7fff) && ((i0 & 0x7fffffff) != 0), 0))
     return x + x;
   if (__builtin_expect ((ix | i0 | i1) == 0, 0))
-    return -HUGE_VALL + x;  /* -inf and overflow exception.  */
+    /* -inf or inf and divide-by-zero exception.  */
+    return ((n < 0 && (n & 1) != 0) ? 1.0L : -1.0L) / 0.0L;
   if (__builtin_expect (se & 0x8000, 0))
     return zero / (zero * x);
   sign = 1;
diff --git a/sysdeps/x86_64/fpu/libm-test-ulps b/sysdeps/x86_64/fpu/libm-test-ulps
index e785148..b3b40ef 100644
--- a/sysdeps/x86_64/fpu/libm-test-ulps
+++ b/sysdeps/x86_64/fpu/libm-test-ulps
@@ -8615,6 +8615,11 @@ idouble: 1
 ifloat: 2
 
 # yn
+Test "yn (-10, 1.0)":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
 Test "yn (0, 0.125)":
 ildouble: 1
 ldouble: 1

-- 
Joseph S. Myers
joseph@codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]