Re: [PATCH 2/3] libm: Remove __ieee754_gamma_r variants

Keith Packard via Newlib <[email protected]>
Newsgroups gmane.comp.lib.newlib
Message-ID <[email protected]>
Corinna Vinschen via Newlib <[email protected]> writes:

> Nevertheless, the symbols have to be exported for backward compatibility.
> So you're saying aliasing gamma_r to lgamma_r and gammaf_r to lgammaf_r
> in the DLLs export table would be sufficient?

It depends if you want the pre-2002 functionality or the post-2002
functionality.

Before 2002, gamma_r and gammaf_r were as BSD originally specified them,
returning the log of gamma (ln(|Γ(x)|)) with the sign of gamma stored
through the second, int *, argument. In 2002, this patch was made to
er_gamma.c:

$ git show 0953fe640f177b565578ed7ecc77169ec1a914fa er_gamma.c

diff --git a/newlib/libm/math/er_gamma.c b/newlib/libm/math/er_gamma.c
index a7183c50f..3c0e241e5 100644
@@ -28,5 +28,5 @@
 	double x; int *signgamp;
 #endif
 {
-	return __ieee754_lgamma_r(x,signgamp);
+	return __ieee754_exp (__ieee754_lgamma_r(x,signgamp));
 }

Before this patch, __ieee754_gamma_r was simply another name for
__ieee754_lgamma_r. After this patch, __ieee754_gamma_r became something
that doesn't exist in any other math library: it returns |Γ(x)| and
stores the sign through the second, int *, argument. Internally, this is
used in w_gamma.c, w_tgamma.c, wr_gamma.c.

w_tgamma.c uses it correctly:

	y = __ieee754_gamma_r(x,&local_signgam);
	if (local_signgam < 0) y = -y;

w_gamma.c, which exports the 'gamma' function uses it *incorrectly* --
it didn't change after the above patch, and so it unexpectedly changed
from returning ln(|Γ(x)|) to returning |Γ(x)|. Applications using
'gamma' instead of 'tgamma' will be getting the wrong answer for some
parameters.

I have to assume this was just an oversight. In 2009, another patch to
w_gamma.c adds a comment explicitly stating that gamma and gamma_r
return ln(|Γ(x)|), when in fact they had been changed to
|Γ(x)| due to the change to __ieee754_gamma_r in the above patch.

Even today, wr_gamma.c says:

	double gamma_r(double x, int *signgamp) /* wrapper lgamma_r */

which is incorrect, as it calls __ieee754_gamma_r.

I see a couple of options here:

 1) Leave things as they are. This makes the 'gamma' family of functions
    incompatible with all other libc implementations and creates a trap
    for applications expecting either lgamma or tgamma values.

 2) Finish the work started in 2002 and make the 'gamma' family
    compatible with their 'tgamma' equivalents. This is what my patch
    does. This makes newlib compatible with 4.4 BSD libc, and leaves
    'gamma' returning the same value anytime that value is non-negative.

 3) Revert the 2002 change so that all of the 'gamma' family return the
    same value as their lgamma equivalents. That would make gamma_r
    useful again, as an alias for lgamma_r. This would make newlib
    compatible with glibc.

 4) Remove the 'gamma' family completely. Given that the meaning of
    'gamma' differs between 4.4 BSD and glibc, it would be safest to
    force applications to select between tgamma and lgamma.

I chose option 2 because that offers the best API compatibility -- the
gamma functions return the same value for most arguments (any positive
arguments, and half of negative arguments).

Any code using the gamma_r functions are likely expecting that to return
lgamma_r (as documented in several places). I can't see how we can leave
that function in the library as-is responsibly.

-- 
-keith
signature.asc (application/pgp-signature, 832 B)
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEEw4O3eCVWE9/bQJ2R2yIaaQAAABEFAl9H5/cACgkQ2yIaaQAA
ABFl3A/9GcECT3AqBeJO9swS95GRiAhpAFxqaPOilk8dWcV6dP+ireZOL62dsXYl
QKdPJPZRghGcfNI2P99CvV9vEAa/IXtX94zn/cY+TfpG8HNNEYCWb8BPXxmz5igS
OFgRdfEa6pGRlZq9wZb7g4Dns62KVn8665PObRsdtfu5uSdhSCKXZ9GEBgoq7EUa
B10dQdHn5XesNJK0efyGvs/BcO6gFH2NEYdALvp52fCc07Prcov1eMGtXIsTDr3T
oK1kEYveJe+MeIJR2evo5rmj/+n7CQ4ESOrzB2LVZPeAE6X+KyOiMWlTWSKLFZCl
BML1y22M2Sa9umq2kAlNEi+GGNJ1vuYH1pdmG/eeh+OLokfm6hjenHJNFRkk5W1c
XBIXQ8Clchf3+vez5gNkpeCftPv0quUAULha3IGpWVza1X/PRY/VnyIu7/gxA+8s
imhJkWWbSB+KbX2Uhho3LbJmHeVuTIIRVALVIhe9T+3OyMR6rvQyhlXUASz2xq+X
hKw0JQrFJI+/hLC6o8B74KPPVCN6YkIFwxzObj5cdeGPZiZVIuMZHuaNw8iXHRd5
R+9zSB/KpQ9jxbxRv7CyodlTDKGWHcc4P6CiNKf/vPSgFkPJr+tNK5x/yBcazS/2
EKWD5/aiV3+zhETmtWmU8boZdFYp1nu46aQ1r2RfxrW82kbQfzY=
=ZFUM
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.