Ejemplo n.º 1
0
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));
}
Ejemplo n.º 2
0
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));
}
Ejemplo n.º 3
0
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));
}