static double neg_gam(double x) { int sgn = 1; struct Double lg, lsine; double y, z; y = ceil(x); if (y == x) /* Negative integer. */ if (_IEEE) return ((x - x) / zero); else return (infnan(ERANGE)); z = y - x; if (z > 0.5) z = one - z; y = 0.5 * y; if (y == ceil(y)) sgn = -1; if (z < .25) z = sin(M_PI*z); else z = cos(M_PI*(0.5-z)); /* Special case: G(1-x) = Inf; G(x) may be nonzero. */ if (x < -170) { if (x < -190) return ((double)sgn*tiny*tiny); y = one - x; /* exact: 128 < |x| < 255 */ lg = large_gam(y); lsine = __log__D(M_PI/z); /* = TRUNC(log(u)) + small */ lg.a -= lsine.a; /* exact (opposite signs) */ lg.b -= lsine.b; y = -(lg.a + lg.b); z = (y + lg.a) + lg.b; y = __exp__D(y, z); if (sgn < 0) y = -y; return (y); } y = one-x; if (one-y == x) y = tgamma(y); else /* 1-x is inexact */ y = -x*tgamma(-x); if (sgn < 0) y = -y; return (M_PI / (y*z)); }
double tgamma(double x) { struct Double u; if (x >= 6) { if(x > 171.63) return (x / zero); u = large_gam(x); return(__exp__D(u.a, u.b)); } else if (x >= 1.0 + LEFT + x0) return (small_gam(x)); else if (x > 1.e-17) return (smaller_gam(x)); else if (x > -1.e-17) { if (x != 0.0) u.a = one - tiny; /* raise inexact */ return (one/x); } else if (!finite(x)) return (x - x); /* x is NaN or -Inf */ else return (neg_gam(x)); }
double tgamma(double x) { struct Double u; #if _IEEE endian = (*(int *) &one) ? 1 : 0; #endif if (x >= 6) { if(x > 171.63) if (_IEEE) return (x/zero); else return (infnan(ERANGE)); u = large_gam(x); return(__exp__D(u.a, u.b)); } else if (x >= 1.0 + LEFT + x0) return (small_gam(x)); else if (x > 1.e-17) return (smaller_gam(x)); else if (x > -1.e-17) { if (x == 0.0) { if (!_IEEE) return (infnan(ERANGE)); } else { u.a = one - tiny; /* raise inexact */ } return (one/x); } else if (!finite(x)) { if (_IEEE) /* x = NaN, -Inf */ return (x - x); else return (infnan(EDOM)); } else return (neg_gam(x)); }