public inbox for newlib@sourceware.org
 help / color / mirror / Atom feed
From: "Keith Packard" <keithp@keithp.com>
To: Corinna Vinschen via Newlib <newlib@sourceware.org>,
	newlib@sourceware.org
Cc: Corinna Vinschen <vinschen@redhat.com>
Subject: Re: [PATCH 2/3] libm: Remove __ieee754_gamma_r variants
Date: Thu, 27 Aug 2020 10:05:59 -0700	[thread overview]
Message-ID: <87pn7cdnns.fsf@keithp.com> (raw)
In-Reply-To: <20200827072411.GT3272@calimero.vinschen.de>

[-- Attachment #1: Type: text/plain, Size: 3459 bytes --]

Corinna Vinschen via Newlib <newlib@sourceware.org> 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

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

  reply	other threads:[~2020-08-27 17:06 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-26 17:03 [PATCH 0/3] libm: Clean up gamma functions Keith Packard
2020-08-26 17:03 ` [PATCH 1/3] libm: Fix sign value returned from __ieee754_lgamma*_r(-0) Keith Packard
2020-08-26 17:03 ` [PATCH 2/3] libm: Remove __ieee754_gamma_r variants Keith Packard
2020-08-26 18:20   ` Corinna Vinschen
2020-08-26 19:10     ` Keith Packard
2020-08-27  7:24       ` Corinna Vinschen
2020-08-27 17:05         ` Keith Packard [this message]
2020-08-28  8:19           ` Corinna Vinschen
2020-08-28  8:34             ` Corinna Vinschen
2020-09-01 16:33               ` Fabian Schriever
2020-09-01 17:23                 ` Keith Packard
2020-09-02  8:03                   ` Corinna Vinschen
2020-09-02 20:37                     ` Keith Packard
2020-09-03  8:04                       ` Corinna Vinschen
2020-09-03 15:59                         ` Brian Inglis
2020-09-03 21:25                           ` Keith Packard
2020-09-03 22:09                             ` Brian Inglis
2020-09-04  0:01                               ` Keith Packard
2020-09-04  0:27                                 ` Brian Inglis
2020-09-04  1:37                                   ` Keith Packard
2020-09-04 13:03                                     ` Corinna Vinschen
2020-09-04 16:19                                       ` Keith Packard
2020-08-26 17:03 ` [PATCH 3/3] libm: Adjust errno/exception values for gamma/lgamma Keith Packard
     [not found]   ` <SN5P110MB0383012287522E8285674CAB9A550@SN5P110MB0383.NAMP110.PROD.OUTLOOK.COM>
2020-08-27 17:55     ` Fw: " C Howland
2020-08-27 19:28       ` Brian Inglis
     [not found] ` <SN5P110MB0383186ECD9B028A4B0E2ECC9A550@SN5P110MB0383.NAMP110.PROD.OUTLOOK.COM>
2020-08-27 17:43   ` Fw: [PATCH 0/3] libm: Clean up gamma functions C Howland
2020-08-27 23:59     ` Keith Packard
2020-08-28  2:03       ` Brian Inglis
2020-08-28  3:13         ` Keith Packard
2020-08-28  3:51           ` Brian Inglis
2020-08-28 17:13             ` Keith Packard
2020-08-28 18:29           ` Joseph Myers
2020-08-28 19:32             ` Keith Packard
2020-08-28 19:53               ` Joseph Myers

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87pn7cdnns.fsf@keithp.com \
    --to=keithp@keithp.com \
    --cc=newlib@sourceware.org \
    --cc=vinschen@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).