Bug 1837

Summary: tgamma() is incorrectly implemented
Product: uClibc Reporter: r.c.poss
Component: Standard ComplianceAssignee: unassigned
Status: NEW ---    
Severity: major CC: buildroot, uclibc-cvs
Priority: P5    
Version: 0.9.32   
Target Milestone: ---   
Hardware: All   
OS: Linux   
Host: Target:
Build:

Description r.c.poss 2010-05-25 22:18:14 UTC
As per the ISO standard, tgamma(x) should compute Gamma(x), while lgamma(x) computes ln(Gamma(x)). The current implementation aliases tgamma and lgamma, which is incorrect.

This was identified in Sept 2009, as per the comment in e_lgamma_r.c:

"""
/* FIXME! Looks like someone just used __ieee754_gamma_r,
 * believing it's a "true" gamma function, but it was not!
 * Our tgamma is WRONG.
 */
"""

(Denis Vlasenko, 2009-09-18)

The function tgamma() thus needs to be replaced entirely.

A "quick and dirty" fix is to rewrite as follows:

"""
        double y;
        int local_signgam;
        y = __ieee754_lgamma_r(x, &local_signgam);
        return local_signgam * exp(y);
"""

This provides relatively accurate results for small inputs, but diverges for large inputs.

An alternate implementation can be found in FreeBSD's source, in /scratch/usr/src/lib/msun/bsdsrc/b_tgamma.c.
Comment 1 Bernhard Reutner-Fischer 2011-02-09 19:40:35 UTC
Care to submit a tested, proper patch?
See http://uclibc.org/developing.html#contrib for instructions.

Thanks!