On 11/3/18 10:09 PM, Jeff Law wrote:
On 10/23/18 7:45 PM, Ed Smith-Rowland wrote:
Greetings,

This is an almost trivial patch to get the correct sign for tgammaq.

I don't have a testcase as I don't know where to put one.

OK?

Ed Smith-Rowland



tgammaq.CL

2018-10-24  Edward Smith-Rowland  <3dw...@verizon.net>

        PR libquadmath/68686
        * math/tgammaq.c: Correct sign for negative argument.
I don't have the relevant background to evaluate this for correctness.
Can you refer back to any kind of documentation which indicates what the
sign of the return value ought to be?

Alternately, if you can point to the relevant code in glibc that handles
the resultant sign, that'd be useful too.

Note that Joseph's follow-up doesn't touch on the gamma problem AFAICT,
but instead touches on the larger issues around trying to keep the
quadmath implementations between glibc and gcc more in sync.

Jeff

Thank you for (re)considering this.The maths here can be read from a very good NIST website:

For the functional formulas referred to below - https://dlmf.nist.gov/5.5

For cool pictures - https://dlmf.nist.gov/5.3#i
(Aside: the reciprocal gamma function is entire - possessing no poles or other analytic complications anywhere in the complex plane.  A rgamma function might be a nice addition to the C family and to TS 18661-1 for that matter.)

For a table of extrema (Table 5.4.1) - https://dlmf.nist.gov/5.4#iii
These would be nice tests for accuracy as well as sign.

TL;DR:
======

Either follow the factorial-like recursion Gamma(x+1) = x Gamma(x) [DLMF 5.5.1] backwards:
    Gamma(x-1) = Gamma(x) / (x-1)
Given that Gamma(x) is positive for x > 0 this will give alternating negative signs if you start with, say, x=1/2 and keep going.
A cooler formula is [DLMF 5.5.3]:
    Gamma(x) Gamma(1-x) = pi / sin(pi x)
Start with x = 3/2 and continue with higher odd half integers to see the sign alternation.

GLibC
=====
I looked in glibc.  Unfortunately, I see how they have the same mistake:
glibc/math/w_tgammal_compat.c:
    long double
    __tgammal(long double x)
    {
        int local_signgam;
        long double y = __ieee754_gammal_r(x,&local_signgam);
        ...
        return local_signgam < 0 ? - y : y;
    }
I'm very sure this is where tgammaq came from.
Ditto for glibc/math/w_tgamma_compat.c and glibc/math/w_tgammaf_compat.c.

This fix will need to be done upstream.
Ed

Reply via email to