summaryrefslogtreecommitdiff
path: root/libm/e_lgamma_r.c
diff options
context:
space:
mode:
Diffstat (limited to 'libm/e_lgamma_r.c')
-rw-r--r--libm/e_lgamma_r.c98
1 files changed, 67 insertions, 31 deletions
diff --git a/libm/e_lgamma_r.c b/libm/e_lgamma_r.c
index 5e1b373c0..82005ea17 100644
--- a/libm/e_lgamma_r.c
+++ b/libm/e_lgamma_r.c
@@ -1,4 +1,3 @@
-/* @(#)er_lgamma.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -10,10 +9,6 @@
* ====================================================
*/
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: e_lgamma_r.c,v 1.7 1995/05/10 20:45:42 jtc Exp $";
-#endif
-
/* __ieee754_lgamma_r(x, signgamp)
* Reentrant version of the logarithm of the Gamma function
* with user provide pointer for the sign of Gamma(x).
@@ -84,14 +79,7 @@ static char rcsid[] = "$NetBSD: e_lgamma_r.c,v 1.7 1995/05/10 20:45:42 jtc Exp $
#include "math.h"
#include "math_private.h"
-libm_hidden_proto(floor)
-libm_hidden_proto(fabs)
-
-#ifdef __STDC__
static const double
-#else
-static double
-#endif
two52= 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
half= 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
@@ -159,22 +147,13 @@ w4 = -5.95187557450339963135e-04, /* 0xBF4380CB, 0x8C0FE741 */
w5 = 8.36339918996282139126e-04, /* 0x3F4B67BA, 0x4CDAD5D1 */
w6 = -1.63092934096575273989e-03; /* 0xBF5AB89D, 0x0B9E43E4 */
-#ifdef __STDC__
static const double zero= 0.00000000000000000000e+00;
-#else
-static double zero= 0.00000000000000000000e+00;
-#endif
static
#ifdef __GNUC__
-inline
-#endif
-#ifdef __STDC__
- double sin_pi(double x)
-#else
- double sin_pi(x)
- double x;
+__inline__
#endif
+double sin_pi(double x)
{
double y,z;
int n,ix;
@@ -218,13 +197,7 @@ inline
return -y;
}
-
-#ifdef __STDC__
- double attribute_hidden __ieee754_lgamma_r(double x, int *signgamp)
-#else
- double attribute_hidden __ieee754_lgamma_r(x,signgamp)
- double x; int *signgamp;
-#endif
+double __ieee754_lgamma_r(double x, int *signgamp)
{
double t,y,z,nadj=0,p,p1,p2,p3,q,r,w;
int i,hx,lx,ix;
@@ -235,7 +208,11 @@ inline
*signgamp = 1;
ix = hx&0x7fffffff;
if(ix>=0x7ff00000) return x*x;
- if((ix|lx)==0) return one/zero;
+ if((ix|lx)==0) {
+ if (signbit(x))
+ *signgamp = -1;
+ return one/zero;
+ }
if(ix<0x3b900000) { /* |x|<2**-70, return -log(|x|) */
if(hx<0) {
*signgamp = -1;
@@ -317,3 +294,62 @@ inline
if(hx<0) r = nadj - r;
return r;
}
+
+strong_alias(__ieee754_lgamma_r, lgamma_r)
+libm_hidden_def(lgamma_r)
+
+/* __ieee754_lgamma(x)
+ * Return the logarithm of the Gamma function of x.
+ */
+double __ieee754_lgamma(double x)
+{
+ return __ieee754_lgamma_r(x, &signgam);
+}
+
+strong_alias(__ieee754_lgamma, lgamma);
+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.
+ */
+strong_alias(__ieee754_lgamma_r, gamma_r)
+strong_alias(__ieee754_lgamma, gamma)
+libm_hidden_def(gamma)
+
+
+/* double tgamma(double x)
+ * Return the Gamma function of x.
+ */
+double tgamma(double x)
+{
+ int sign_of_gamma;
+ int32_t hx;
+ u_int32_t lx;
+
+ /* We don't have a real gamma implementation now. We'll use lgamma
+ and the exp function. But due to the required boundary
+ conditions we must check some values separately. */
+
+ EXTRACT_WORDS(hx, lx, x);
+
+ if (((hx & 0x7fffffff) | lx) == 0) {
+ /* Return value for x == 0 is Inf with divide by zero exception. */
+ return 1.0 / x;
+ }
+ if (hx < 0 && (u_int32_t)hx < 0xfff00000 && rint(x) == x) {
+ /* Return value for integer x < 0 is NaN with invalid exception. */
+ return (x - x) / (x - x);
+ }
+ if ((u_int32_t)hx == 0xfff00000 && lx == 0) {
+ /* x == -Inf. According to ISO this is NaN. */
+ return x - x;
+ }
+
+ x = exp(lgamma_r(x, &sign_of_gamma));
+ return sign_of_gamma >= 0 ? x : -x;
+}
+libm_hidden_def(tgamma)