[PATCH v6 3/3] math: Remove the SVID error handling from tgammaf
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Wed Nov 5 10:38:25 GMT 2025
On 04/11/25 17:38, Wilco Dijkstra wrote:
> 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).
Right, I am leaning more to using __math_erangef here since it does simplify
the code a bit.
>
> 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