Summary: Historical confusion abounds; avoid gamma()
and use tgamma()
.
It's the math library, not gcc (the compiler), that implements these functions. If you're seeing different behavior on MacOS and Ubuntu, it's probably because Ubuntu uses glibc and MacOS uses something else.
There is no function named gamma
in the ISO C standard library.
There are standard functions called lgamma
and tgamma
. Quoting N1570 (the latest draft of the 2011 ISO C standard) sections 17.12.8.3 and 17.12.8.4:
#include <math.h>
double lgamma(double x);
float lgammaf(float x);
long double lgammal(long double x);
The lgamma functions compute the natural logarithm of the absolute value of gamma of x. A range error occurs if x is too large. A pole error may occur if x is a negative integer or zero.
#include <math.h>
double tgamma(double x);
float tgammaf(float x);
long double tgammal(long double x);
The tgamma functions compute the gamma function of x. A domain error or pole error may occur if x is a negative integer or zero. A range error occurs if the magnitude of x is too large and may occur if the magnitude of x is too small.
These functions do not appear in the 1990 ISO C standard. They were introduced by C99.
Quoting the Linux man page for gamma
:
These functions are deprecated: instead, use either the tgamma(3) or the lgamma(3) functions, as appropriate.
For the definition of the Gamma function, see tgamma(3).
*BSD version
The libm in 4.4BSD and some versions of FreeBSD had a gamma() function that computes the Gamma function, as one would expect.
glibc version
Glibc has a gamma() function that is equivalent to lgamma(3) and computes the natural logarithm of the Gamma function.
and an historical note:
4.2BSD had a gamma() that computed ln(|Gamma(|x|)|), leaving the sign of Gamma(|x|) in the external integer signgam. In 4.3BSD the name was changed to lgamma(3), and the man page promises
"At some time in the future the name gamma will be rehabilitated and used for the Gamma function"
This did indeed happen in 4.4BSD, where gamma() computes the Gamma function (with no effect on signgam). However, this came too late, and we now have tgamma(3), the "true gamma" function.
Since gamma
is not a standard C function, compiling with gcc -std=c99 -pedantic
or gcc -std=c11 -pedantic
should produce at least a warning for any attempt to call it.
You should probably use tgamma()
(or lgamma()
if you want the natural logarithm) and avoid using gamma()
.
The C standard doesn't seem to say what the Gamma function is. The Linux tgamma() man page does (but if you're trying to use it you probably already know what it is):
The Gamma function is defined by
Gamma(x) = integral from 0 to infinity of t^(x-1) e^-t dt
It is defined for every real number except for nonpositive integers.
For nonnegative integral m one hasGamma(m+1) = m!
and, more generally, for all x:
Gamma(x+1) = x * Gamma(x)
Furthermore, the following is valid for all values of x outside the poles:
Gamma(x) * Gamma(1 - x) = PI / sin(PI * x)