[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