[COMMITTED] math: Sync lgammaf with CORE-MATH
Paul Zimmermann
Paul.Zimmermann@inria.fr
Fri Mar 20 08:06:51 GMT 2026
Hi,
while re-running exhaustive checks with CORE-MATH test suite, I hit:
zimmerma@thym:~/svn/core-math$ CORE_MATH_CHECK_STD=true CORE_MATH_LAUNCHER="/tmp/lib/ld-linux-x86-64.so.2 --library-path /tmp/lib:/usr/lib/x86_64-linux-gnu" LDFLAGS="-L /tmp/lib" ./check.sh lgammaf
Running exhaustive check in --rndn mode...
Error, signgam wrong for x=-0x1.ecp+6
expected 1, got -1
Is signgam defined for negative integers? The reference manual is not very
clear about this:
The sign of the
Gamma function is returned in the external integer signgam declared in
<math.h>. It is 1 when the Gamma function is positive or zero, -1 when
it is negative.
I see on https://pubs.opengroup.org/onlinepubs/9799919799/functions/lgamma.html:
If \(x\) is NaN, -Inf, or a negative integer, the value of signgam is unspecified.
Should we add this in the manual?
Paul
> From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> Date: Thu, 19 Mar 2026 13:53:20 -0300
>
> It removes some unnecessary corner-case checks and uses a slightly
> different binary algorithm for the hard-case database binary search.
>
> Checked on aarch64-linux-gnu, arm-linux-gnueabihf,
> powerpc64le-linux-gnu, i686-linux-gnu, and x86_64-linux-gnu.
> ---
> SHARED-FILES | 2 +-
> sysdeps/ieee754/flt-32/e_lgammaf_r.c | 36 ++++++++++------------------
> 2 files changed, 14 insertions(+), 24 deletions(-)
>
> diff --git a/SHARED-FILES b/SHARED-FILES
> index c3e8e0f5ae..5a676e1a48 100644
> --- a/SHARED-FILES
> +++ b/SHARED-FILES
> @@ -272,7 +272,7 @@ core-math:
> sysdeps/ieee754/flt-32/e_coshf.c
> # src/binary32/tgamma/tgammaf.c, revision 8ea8ea35
> sysdeps/ieee754/flt-32/e_gammaf_r.c
> - # src/binary32/lgamma/lgammaf.c, revision bc385c2
> + # src/binary32/lgamma/lgammaf.c, revision 8ea8ea35
> sysdeps/ieee754/flt-32/e_lgammaf_r.c
> # src/binary32/log10/log10f.c, revision ebff4c43
> sysdeps/ieee754/flt-32/e_log10f.c
> diff --git a/sysdeps/ieee754/flt-32/e_lgammaf_r.c b/sysdeps/ieee754/flt-32/e_lgammaf_r.c
> index 2fb4784b59..7b947cd979 100644
> --- a/sysdeps/ieee754/flt-32/e_lgammaf_r.c
> +++ b/sysdeps/ieee754/flt-32/e_lgammaf_r.c
> @@ -1,10 +1,10 @@
> /* Correctly-rounded logarithm of the absolute value of the gamma function
> for binary32 value.
>
> -Copyright (c) 2023, 2024 Alexei Sibidanov.
> +Copyright (c) 2023-2026 Alexei Sibidanov.
>
> This file is part of the CORE-MATH project
> -project (file src/binary32/lgamma/lgammaf.c, revision bc385c2).
> +project (file src/binary32/lgamma/lgammaf.c, revision 8ea8ea35).
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> @@ -159,7 +159,7 @@ __lgammaf_r (float x, int *signgamp)
> return x + x; /* nan */
> }
> if (__glibc_unlikely (fx == x))
> - {
> + { /* x integer */
> if (x <= 0.0f)
> {
> *signgamp = asuint (x) >> 31 ? -1 : 1;
> @@ -204,15 +204,11 @@ __lgammaf_r (float x, int *signgamp)
> f = (c0 * s) * as_r8 (s, rn) / as_r8 (s, rd) - as_ln (z);
> }
> else
> - {
> + { /* |x| >= 0x1.52p-1 */
> if (ax > 0x1.afc1ap+1f)
> {
> - if (__glibc_unlikely (x > 0x1.895f1cp+121f))
> + if (__glibc_unlikely (x >= 0x1.895f1cp+121f))
> return __math_oflowf (0);
> -
> - /* |x|>=2**23, must be -integer */
> - if (__glibc_unlikely (x < 0.0f && ax > 0x1p+23f))
> - return __math_divzerof (0);
> double lz = as_ln (z);
> f = (z - 0.5) * (lz - 1) + 0x1.acfe390c97d69p-2;
> if (ax < 0x1.0p+20f)
> @@ -270,12 +266,6 @@ __lgammaf_r (float x, int *signgamp)
> -0x1.3a6c8295b4445p-1, -0x1.da44e8b810024p-3,
> -0x1.9061e81c77e4ap-5
> };
> - if (x < 0.0f)
> - {
> - int ni = floorf (-2 * x);
> - if ((ni & 1) == 0 && ni == -2 * x)
> - return __math_divzerof (0);
> - }
> const double c0 = 0x1.3cc0e6a0106b3p+2;
> static const double rd[] =
> {
> @@ -351,15 +341,15 @@ __lgammaf_r (float x, int *signgamp)
> if (__glibc_unlikely (tl <= 31u))
> {
> t = asuint (x);
> - int a = 0, b = array_length (tb) - 1;
> - while (a < b)
> - { /* Binary search. */
> - int m = (a + b) >> 1;
> - uint32_t tbi = asuint (tb[m].x);
> - if (t > tbi)
> - a = m + 1;
> + int a = 0, b = array_length (tb);
> + /* invariant: t.u < tb[0].x.u or tb[a].x.u <= t.u < tb[b].x.u */
> + while (a + 1 < b)
> + {
> + int i = (a + b) / 2;
> + if (t < asuint (tb[i].x))
> + b = i;
> else
> - b = m;
> + a = i;
> }
> if (t == asuint (tb[a].x))
> return tb[a].f + tb[a].df;
> --
> 2.43.0
>
>
More information about the Libc-alpha
mailing list