diff options
author | Joseph Myers <joseph@codesourcery.com> | 2013-12-04 14:39:37 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2013-12-04 14:39:37 +0000 |
commit | 699ff83712b5796ac50ed332d9dad55d38450e81 (patch) | |
tree | 8e2470bbcf5d1d18813aa9d063771b083c8667af | |
parent | 5b118558f9fb0620508d51c34c2cb5ba4f1f01c2 (diff) | |
download | glibc-699ff83712b5796ac50ed332d9dad55d38450e81.zip glibc-699ff83712b5796ac50ed332d9dad55d38450e81.tar.gz glibc-699ff83712b5796ac50ed332d9dad55d38450e81.tar.bz2 |
Fix Bessel function error handling (bug 6807, bug 15901).
-rw-r--r-- | ChangeLog | 28 | ||||
-rw-r--r-- | NEWS | 24 | ||||
-rw-r--r-- | math/libm-test.inc | 66 | ||||
-rw-r--r-- | math/w_j0.c | 7 | ||||
-rw-r--r-- | math/w_j0f.c | 7 | ||||
-rw-r--r-- | math/w_j0l.c | 7 | ||||
-rw-r--r-- | math/w_j1.c | 7 | ||||
-rw-r--r-- | math/w_j1f.c | 7 | ||||
-rw-r--r-- | math/w_j1l.c | 7 | ||||
-rw-r--r-- | math/w_jn.c | 7 | ||||
-rw-r--r-- | math/w_jnf.c | 7 | ||||
-rw-r--r-- | sysdeps/i386/fpu/libm-test-ulps | 3 | ||||
-rw-r--r-- | sysdeps/ieee754/k_standard.c | 16 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128/e_jnl.c | 2 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128ibm/e_jnl.c | 2 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-96/e_jnl.c | 3 | ||||
-rw-r--r-- | sysdeps/x86_64/fpu/libm-test-ulps | 5 |
17 files changed, 156 insertions, 49 deletions
@@ -1,3 +1,31 @@ +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. + 2013-11-12 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> * sysdeps/unix/sysv/linux/powerpc/Makefile (abi-variants): Rename @@ -9,18 +9,18 @@ Version 2.19 * The following bugs are resolved with this release: - 156, 387, 431, 832, 2801, 6786, 6787, 7003, 9954, 10253, 10278, 11087, - 11157, 11214, 13028, 13982, 13985, 14029, 14032, 14143, 14155, 14547, - 14699, 14752, 14876, 14910, 15004, 15048, 15218, 15268, 15277, 15308, - 15362, 15374, 15400, 15425, 15427, 15483, 15522, 15531, 15532, 15601, - 15608, 15609, 15610, 15632, 15640, 15670, 15672, 15680, 15681, 15723, - 15734, 15735, 15736, 15748, 15749, 15754, 15760, 15763, 15764, 15797, - 15799, 15825, 15844, 15847, 15849, 15855, 15856, 15857, 15859, 15867, - 15886, 15887, 15890, 15892, 15893, 15895, 15897, 15905, 15909, 15917, - 15919, 15921, 15923, 15939, 15948, 15963, 15966, 15985, 15988, 15997, - 16032, 16034, 16036, 16037, 16041, 16055, 16071, 16072, 16074, 16077, - 16078, 16103, 16112, 16143, 16144, 16146, 16150, 16151, 16153, 16167, - 16172, 16195, 16214, 16245, 16271, 16283, 16289. + 156, 387, 431, 832, 2801, 6786, 6787, 6807, 7003, 9954, 10253, 10278, + 11087, 11157, 11214, 13028, 13982, 13985, 14029, 14032, 14143, 14155, + 14547, 14699, 14752, 14876, 14910, 15004, 15048, 15218, 15268, 15277, + 15308, 15362, 15374, 15400, 15425, 15427, 15483, 15522, 15531, 15532, + 15601, 15608, 15609, 15610, 15632, 15640, 15670, 15672, 15680, 15681, + 15723, 15734, 15735, 15736, 15748, 15749, 15754, 15760, 15763, 15764, + 15797, 15799, 15825, 15844, 15847, 15849, 15855, 15856, 15857, 15859, + 15867, 15886, 15887, 15890, 15892, 15893, 15895, 15897, 15901, 15905, + 15909, 15917, 15919, 15921, 15923, 15939, 15948, 15963, 15966, 15985, + 15988, 15997, 16032, 16034, 16036, 16037, 16041, 16055, 16071, 16072, + 16074, 16077, 16078, 16103, 16112, 16143, 16144, 16146, 16150, 16151, + 16153, 16167, 16172, 16195, 16214, 16245, 16271, 16283, 16289. * The public headers no longer use __unused nor __block. This change is to support compiling programs that are derived from BSD sources and use 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 |