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;
 }




Reply via email to