cc [ flags ] -I/usr/local/include file(s) -L/usr/local/lib -lmcw [ ... ] #include <mathcw.h> extern int signgam; extern float lgammaf (float x); extern double lgamma (double x); extern long double lgammal (long double x); extern __float80 lgammaw (__float80 x); extern __float128 lgammaq (__float128 x); extern long_long_double lgammall (long_long_double x); extern decimal_float lgammadf (decimal_float x); extern decimal_double lgammad (decimal_double x); extern decimal_long_double lgammadl (decimal_long_double x); extern decimal_long_long_double lgammadll (decimal_long_long_double x);
NB: Functions with prototypes containing underscores in type names may be available only with certain extended compilers.
The Gamma function, the generalized factorial function, is defined by the integral
In traditional mathematical notation, Gamma is spelled as the uppercase Greek letter, and the lowercase Greek letter gamma refers either to the Euler constant, gamma = 0.57721566489... or when followed by two arguments, as in gamma(a,x), to the incomplete Gamma function, a function not currently provided by this library.Gamma(x) = integral(t = 0:infinity) t**(x-1) exp(-t) dt
The Gamma function satisfies this simple recursion relation:
For positive integral arguments, the Gamma function is related to the factorial function byGamma(x + 1) = x Gamma(x)
Gamma(n + 1) = n! = n * (n - 1) * (n - 2) * ... * 1,
and
Gamma(1) = 0! = 1 (by definition).
This function was not standardized in the C language until the 1999 ISO C Standard, and because some historical implementations of the language had unfortunately used gamma(x) for the logarithm of the Gamma function, the C99 function was named tgamma(x) (for true Gamma), rather than Gamma(x), because Standard C library functions must be defined with only lowercase names.
Although the Gamma function grows so quickly that the overflow limit is quickly reached, the log of its absolute value is representable for arguments almost up to the overflow limit.
Because the Gamma function alternates in sign as it crosses the asymptotes at negative integer arguments, and lgamma() uses its absolute value, the sign of Gamma is lost. Consequently, most historical implementations of this function recorded the sign of Gamma in the global variable signgam: -1 if Gamma is negative, and +1 if Gamma is positive. If Gamma underflows to zero, a strong possibility for negative arguments of even modest magnitude, then the sign is -1 if Gamma tends to more negative values around the argument, and otherwise, +1.
The 1999 ISO C Standard dropped the signgam variable, but this implementation continues to provide it. However, because of its omission in the C99 Standard, programs should not rely on the availability of signgam.
Because global variables are unreliable in multithreaded programs, the mathcw library provides an alternate thread-safe version, lgamma_r(x,&sign), that returns the sign of Gamma via the second argument.
Caution: Although lgamma(x) allows representation of tgamma(x) over a much wider range than is possible with tgamma(x) alone, there is mathematically-unavoidable accuracy loss when tgamma(x) is computed from exp(lgamma(x)), so you should avoid the logarithmic form unless you really need large arguments that would cause overflow in tgamma(x).
Caution: Because evaluation order in C is flexible, you should not incorporate the sign in a direct computation to recover Gamma as, e.g., exp((double)signgam * lgamma(x)), but instead, compute the inner function first, temp = lgamma(x), then compute the outer function, exp((double)signgam * temp).