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
This commit is contained in:
Szabolcs Nagy 2012-12-16 20:22:17 +01:00
parent e42a977fe5
commit d8a7619e37
1 changed files with 23 additions and 28 deletions

View File

@ -205,42 +205,36 @@ static long double stirf(long double x)
long double tgammal(long double x) long double tgammal(long double x)
{ {
long double p, q, z; long double p, q, z;
int i, sign;
if (isnan(x)) if (!isfinite(x))
return NAN; return x + INFINITY;
if (x == INFINITY)
return INFINITY;
if (x == -INFINITY)
return x - x;
q = fabsl(x); q = fabsl(x);
if (q > 13.0) { if (q > 13.0) {
sign = 1;
if (q > MAXGAML)
goto goverf;
if (x < 0.0) { if (x < 0.0) {
p = floorl(q); p = floorl(q);
if (p == q)
return (x - x) / (x - x);
i = p;
if ((i & 1) == 0)
sign = -1;
z = q - p; z = q - p;
if (z > 0.5L) { if (z == 0)
return 0 / z;
if (q > MAXGAML) {
z = 0;
} else {
if (z > 0.5) {
p += 1.0; p += 1.0;
z = q - p; z = q - p;
} }
z = q * sinl(PIL * z); z = q * sinl(PIL * z);
z = fabsl(z) * stirf(q); z = fabsl(z) * stirf(q);
if (z <= PIL/LDBL_MAX) {
goverf:
return sign * INFINITY;
}
z = PIL/z; z = PIL/z;
}
if (0.5 * p == floorl(q * 0.5))
z = -z;
} else if (x > MAXGAML) {
z = x * 0x1p16383L;
} else { } else {
z = stirf(x); z = stirf(x);
} }
return sign * z; return z;
} }
z = 1.0; z = 1.0;
@ -268,8 +262,9 @@ goverf:
return z; return z;
small: small:
if (x == 0.0) /* z==1 if x was originally +-0 */
return (x - x) / (x - x); if (x == 0 && z != 1)
return x / x;
if (x < 0.0) { if (x < 0.0) {
x = -x; x = -x;
q = z / (x * __polevll(x, SN, 8)); q = z / (x * __polevll(x, SN, 8));