about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorSzabolcs Nagy <nsz@port70.net>2012-12-16 20:22:17 +0100
committerSzabolcs Nagy <nsz@port70.net>2012-12-16 20:22:17 +0100
commitd8a7619e371ff0f226200f6316abb46dd1192f3d (patch)
tree3d7f33c730381b1563ce512ac0c1e1204f93e5a4 /src
parente42a977fe5dbe48ba45072ab82886e6b5a694487 (diff)
downloadmusl-d8a7619e371ff0f226200f6316abb46dd1192f3d.tar.gz
musl-d8a7619e371ff0f226200f6316abb46dd1192f3d.tar.xz
musl-d8a7619e371ff0f226200f6316abb46dd1192f3d.zip
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.c51
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));