Another 22-years old bug:
2025-12-03 Bruno Haible <[email protected]> tanl: Fix result for negative values. * lib/tanl.c (kernel_tanl): In all code branches, multiply the result with the sign of x. * tests/test-tanl.c (main): Test two small negative values. diff --git a/lib/tanl.c b/lib/tanl.c index ffa4e3c655..908676b1d4 100644 --- a/lib/tanl.c +++ b/lib/tanl.c @@ -164,9 +164,9 @@ kernel_tanl (long double x, long double y, int iy) if ((int) x == 0) { /* generate inexact */ if (iy == -1 && x == 0.0) - return 1.0L / fabs (x); + return 1.0L / fabs (x) * sign; else - return (iy == 1) ? x : -1.0L / x; + return (iy == 1 ? x : -1.0L / x) * sign; } } if (x >= 0.6743316650390625) /* |x| >= 0.6743316650390625 */ @@ -191,12 +191,10 @@ kernel_tanl (long double x, long double y, int iy) { v = (long double) iy; w = (v - 2.0 * (x - (w * w / (w + v) - r))); - if (sign < 0) - w = -w; - return w; + return w * sign; } if (iy == 1) - return w; + return w * sign; else { /* if allow error up to 2 ulp, simply return -1.0/(x+r) here */ @@ -206,7 +204,7 @@ kernel_tanl (long double x, long double y, int iy) z = -1.0 / w; u = (double) z; s = 1.0 + u * u1; - return u + z * (s + u * v); + return (u + z * (s + u * v)) * sign; } } diff --git a/tests/test-tanl.c b/tests/test-tanl.c index f08b036516..a87223463f 100644 --- a/tests/test-tanl.c +++ b/tests/test-tanl.c @@ -41,5 +41,16 @@ main () y = tanl (x); ASSERT (y >= 0.6841368083L && y <= 0.6841368084L); + /* A small negative value. */ + x = -0.1L; + y = tanl (x); + ASSERT (y >= -0.10033467209L && y <= -0.10033467208L); + + /* A very small negative value. */ + x = -0.000000000000000004L; + y = tanl (x); + ASSERT (y >= -0.000000000000000004000000001L + && y <= -0.000000000000000004000000000L); + return test_exit_status; }
