diff options
| author | Szabolcs Nagy <nsz@port70.net> | 2012-12-16 20:22:17 +0100 | 
|---|---|---|
| committer | Szabolcs Nagy <nsz@port70.net> | 2012-12-16 20:22:17 +0100 | 
| commit | d8a7619e371ff0f226200f6316abb46dd1192f3d (patch) | |
| tree | 3d7f33c730381b1563ce512ac0c1e1204f93e5a4 /src | |
| parent | e42a977fe5dbe48ba45072ab82886e6b5a694487 (diff) | |
| download | musl-d8a7619e371ff0f226200f6316abb46dd1192f3d.tar.gz | |
math: tgammal.c fixes
this is not a full rewrite just fixes to the special case logic:
+-0 and non-integer x<INT_MIN inputs incorrectly raised invalid
exception and for +-0 the return value was wrong
so integer test and odd/even test for negative inputs are changed
and a useless overflow test was removed
Diffstat (limited to 'src')
| -rw-r--r-- | src/math/tgammal.c | 51 | 
1 files changed, 23 insertions, 28 deletions
| diff --git a/src/math/tgammal.c b/src/math/tgammal.c index 86782a96..5c1a02a6 100644 --- a/src/math/tgammal.c +++ b/src/math/tgammal.c @@ -205,42 +205,36 @@ static long double stirf(long double x)  long double tgammal(long double x)  {  	long double p, q, z; -	int i, sign; -	if (isnan(x)) -		return NAN; -	if (x == INFINITY) -		return INFINITY; -	if (x == -INFINITY) -		return x - x; +	if (!isfinite(x)) +		return x + INFINITY; +  	q = fabsl(x);  	if (q > 13.0) { -		sign = 1; -		if (q > MAXGAML) -			goto goverf;  		if (x < 0.0) {  			p = floorl(q); -			if (p == q) -				return (x - x) / (x - x); -			i = p; -			if ((i & 1) == 0) -				sign = -1;  			z = q - p; -			if (z > 0.5L) { -				p += 1.0; -				z = q - p; -			} -			z = q * sinl(PIL * z); -			z = fabsl(z) * stirf(q); -			if (z <= PIL/LDBL_MAX) { -goverf: -				return sign * INFINITY; +			if (z == 0) +				return 0 / z; +			if (q > MAXGAML) { +				z = 0; +			} else { +				if (z > 0.5) { +					p += 1.0; +					z = q - p; +				} +				z = q * sinl(PIL * z); +				z = fabsl(z) * stirf(q); +				z = PIL/z;  			} -			z = PIL/z; +			if (0.5 * p == floorl(q * 0.5)) +				z = -z; +		} else if (x > MAXGAML) { +			z = x * 0x1p16383L;  		} else {  			z = stirf(x);  		} -		return sign * z; +		return z;  	}  	z = 1.0; @@ -268,8 +262,9 @@ goverf:  	return z;  small: -	if (x == 0.0) -		return (x - x) / (x - x); +	/* z==1 if x was originally +-0 */ +	if (x == 0 && z != 1) +		return x / x;  	if (x < 0.0) {  		x = -x;  		q = z / (x * __polevll(x, SN, 8)); | 
