diff options
Diffstat (limited to 'libm/e_lgamma_r.c')
-rw-r--r-- | libm/e_lgamma_r.c | 68 |
1 files changed, 60 insertions, 8 deletions
diff --git a/libm/e_lgamma_r.c b/libm/e_lgamma_r.c index 5aacadcfd..075fdc4f0 100644 --- a/libm/e_lgamma_r.c +++ b/libm/e_lgamma_r.c @@ -312,25 +312,77 @@ double lgamma_r(double x, int *signgamp) strong_alias(__ieee754_lgamma_r, lgamma_r) #endif +/* __ieee754_lgamma(x) + * Return the logarithm of the Gamma function of x. + */ +double attribute_hidden __ieee754_lgamma(double x) +{ + return __ieee754_lgamma_r(x, &signgam); +} + /* - * wrapper double gamma_r(double x, int *signgamp) + * wrapper double lgamma(double x) */ -double gamma_r(double x, int *signgamp); -libm_hidden_proto(gamma_r) #ifndef _IEEE_LIBM -double gamma_r(double x, int *signgamp) +double lgamma(double x) { - double y = __ieee754_lgamma_r(x, signgamp); + double y = __ieee754_lgamma_r(x, &signgam); if (_LIB_VERSION == _IEEE_) return y; if (!isfinite(y) && isfinite(x)) { if (floor(x) == x && x <= 0.0) - return __kernel_standard(x, x, 41); /* gamma pole */ - return __kernel_standard(x, x, 40); /* gamma overflow */ + return __kernel_standard(x, x, 15); /* lgamma pole */ + return __kernel_standard(x, x, 14); /* lgamma overflow */ } return y; } #else +strong_alias(__ieee754_lgamma, lgamma); +#endif +libm_hidden_def(lgamma) + + + +/* NB: gamma function is an old name for lgamma. + * It is deprecated. + * Some C math libraries redefine it as a "true gamma", i.e., + * not a ln(|Gamma(x)|) but just Gamma(x), but standards + * introduced tgamma name for that. + */ +#ifndef _IEEE_LIBM +strong_alias(lgamma_r, gamma_r) +strong_alias(lgamma, gamma) +#else strong_alias(__ieee754_lgamma_r, gamma_r) +strong_alias(__ieee754_lgamma, gamma) +#endif + + + +// FIXME! Looks like someone just used __ieee754_gamma_r, +// believing it's a "true" gamma function, but it was not! +// Our tgamma is WRONG. + +/* double tgamma(double x) + * Return the Gamma function of x. + */ +double tgamma(double x) +{ + double y; + int local_signgam; + + y = __ieee754_lgamma_r(x, &local_signgam); // was __ieee754_gamma_r + if (local_signgam < 0) + y = -y; +#ifndef _IEEE_LIBM + if (_LIB_VERSION == _IEEE_) + return y; + if (!isfinite(y) && isfinite(x)) { + if (floor(x) == x && x <= 0.0) + return __kernel_standard(x, x, 41); /* tgamma pole */ + return __kernel_standard(x, x, 40); /* tgamma overflow */ + } #endif -libm_hidden_def(gamma_r) + return y; +} +libm_hidden_def(tgamma) |