[PATCH v6 3/3] math: Remove the SVID error handling from tgammaf

Wilco Dijkstra Wilco.Dijkstra@arm.com
Tue Nov 4 20:38:15 GMT 2025


Hi Adhemerval,

+      if (x == 0.0f)
+       return __math_oflowf_value (r);
+      else if (isinf (r))
+       return __math_oflowf (t >> 31);
       return r;

Right so we end up with zero here (which also gives +-Inf). This is equivalent:

if (x == 0.0f)
  return __math_divzerof (t >> 31);
if (isinf (r))
  return __math_oflowf (t >> 31);

We could write (instead of __math_oflowf_value):

if (isinf (r))
  return __math_erangef (r);

I don't mind adding this interface, but the separate tests do allow more
flexibility (eg. x == 0.0f test can be done at the start of the enclosing if).

   float fx = floorf (x);
   if (__glibc_unlikely (x >= 0x1.18522p+5f))
-    {
-      /* Overflow case.  The original CORE-MATH code returns
-        0x1p127f * 0x1p127f, but apparently some compilers replace this
-        by +Inf.  */
-      return math_narrow_eval (x * 0x1p127f);
-    }
+    return __math_oflowf (0);

OK

   /* compute k only after the overflow check, otherwise the case to integer
      might overflow */
   int k = fx;
   if (__glibc_unlikely (fx == x))
     { /* x is integer */
-      if (x == 0.0f)
-       return 1.0f / x;

OK, cannot ever happen since it's done above.

       if (x < 0.0f)
         return __math_invalidf (0.0f);

OK

       double t0 = 1, x0 = 1;
@@ -121,12 +110,10 @@ __ieee754_gammaf_r (float x, int *signgamp)
       return t0;
     }
   if (__glibc_unlikely (x < -42.0f))
-    { /* negative non-integer */
-      /* For x < -42, x non-integer, |gamma(x)| < 2^-151.  */
-      static const float sgn[2] = { 0x1p-127f, -0x1p-127f };
-      /* Underflows always happens */
-      return math_narrow_eval (0x1p-127f * sgn[k & 1]);
-    }
+    /* negative non-integer */
+    /* For x < -42, x non-integer, |gamma(x)| < 2^-151.  */
+    /* Underflows always happens */
+    return __math_uflowf (k & 1);

OK


@@ -164,13 +151,22 @@ __ieee754_gammaf_r (float x, int *signgamp)
   f *= w;
   uint64_t rt = asuint64 (f);
   float r = f;
+  if (__glibc_unlikely (r == 0))
+    return __math_uflowf (rt >> 63);

OK

   /* Deal with exceptional cases.  */
   if (__glibc_unlikely (((rt + 2) & 0xfffffff) < 8))
     {
-      for (unsigned j = 0; j < sizeof (tb) / sizeof (tb[0]); j++)
+      for (unsigned j = 0; j < array_length (tb); j++)
         if (t == tb[j].u)
           return tb[j].f + tb[j].df;
     }
   return r;
 }

OK


More information about the Libc-alpha mailing list