about summary refs log tree commit diff
path: root/src/math/nextafterl.c
diff options
context:
space:
mode:
authorSzabolcs Nagy <nsz@port70.net>2013-09-02 00:38:51 +0000
committerSzabolcs Nagy <nsz@port70.net>2013-09-05 11:30:07 +0000
commitaf5f6d9556441487e5c66a7a4cfeddf4ed354aa7 (patch)
tree34a31a68753c2851628109713a3462cb4742ef44 /src/math/nextafterl.c
parentff4d6020d1c8aaab4f05e561789d6dad3d7ef083 (diff)
downloadmusl-af5f6d9556441487e5c66a7a4cfeddf4ed354aa7.tar.gz
musl-af5f6d9556441487e5c66a7a4cfeddf4ed354aa7.tar.xz
musl-af5f6d9556441487e5c66a7a4cfeddf4ed354aa7.zip
long double cleanup, initial commit
new ldshape union, ld128 support is kept, code that used the old
ldshape union was rewritten (IEEEl2bits union of freebsd libm is
not touched yet)

ld80 __fpclassifyl no longer tries to handle invalid representation
Diffstat (limited to 'src/math/nextafterl.c')
-rw-r--r--src/math/nextafterl.c81
1 files changed, 37 insertions, 44 deletions
diff --git a/src/math/nextafterl.c b/src/math/nextafterl.c
index edc3cc9c..37e858fb 100644
--- a/src/math/nextafterl.c
+++ b/src/math/nextafterl.c
@@ -6,7 +6,6 @@ long double nextafterl(long double x, long double y)
 	return nextafter(x, y);
 }
 #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
-#define MSB ((uint64_t)1<<63)
 long double nextafterl(long double x, long double y)
 {
 	union ldshape ux, uy;
@@ -15,32 +14,32 @@ long double nextafterl(long double x, long double y)
 		return x + y;
 	if (x == y)
 		return y;
-	ux.value = x;
+	ux.f = x;
 	if (x == 0) {
-		uy.value = y;
-		ux.bits.m = 1;
-		ux.bits.sign = uy.bits.sign;
-	} else if (x < y ^ ux.bits.sign) {
-		ux.bits.m++;
-		if ((ux.bits.m & ~MSB) == 0) {
-			ux.bits.m = MSB;
-			ux.bits.exp++;
+		uy.f = y;
+		ux.i.m = 1;
+		ux.i.se = uy.i.se & 0x8000;
+	} else if ((x < y) == !(ux.i.se & 0x8000)) {
+		ux.i.m++;
+		if (ux.i.m << 1 == 0) {
+			ux.i.m = 1ULL << 63;
+			ux.i.se++;
 		}
 	} else {
-		if ((ux.bits.m & ~MSB) == 0) {
-			ux.bits.exp--;
-			if (ux.bits.exp)
-				ux.bits.m = 0;
+		if (ux.i.m << 1 == 0) {
+			ux.i.se--;
+			if (ux.i.se)
+				ux.i.m = 0;
 		}
-		ux.bits.m--;
+		ux.i.m--;
 	}
-	/* raise overflow if ux.value is infinite and x is finite */
-	if (ux.bits.exp == 0x7fff)
+	/* raise overflow if ux is infinite and x is finite */
+	if ((ux.i.se & 0x7fff) == 0x7fff)
 		return x + x;
-	/* raise underflow if ux.value is subnormal or zero */
-	if (ux.bits.exp == 0)
-		FORCE_EVAL(x*x + ux.value*ux.value);
-	return ux.value;
+	/* raise underflow if ux is subnormal or zero */
+	if ((ux.i.se & 0x7fff) == 0)
+		FORCE_EVAL(x*x + ux.f*ux.f);
+	return ux.f;
 }
 #elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
 long double nextafterl(long double x, long double y)
@@ -51,32 +50,26 @@ long double nextafterl(long double x, long double y)
 		return x + y;
 	if (x == y)
 		return y;
-	ux.value = x;
+	ux.f = x;
 	if (x == 0) {
-		uy.value = y;
-		ux.bits.mlo = 1;
-		ux.bits.sign = uy.bits.sign;
-	} else if (x < y ^ ux.bits.sign) {
-		ux.bits.mlo++;
-		if (ux.bits.mlo == 0) {
-			ux.bits.mhi++;
-			if (ux.bits.mhi == 0)
-				ux.bits.exp++;
-		}
+		uy.f = y;
+		ux.i.lo = 1;
+		ux.i.se = uy.i.se & 0x8000;
+	} else if ((x < y) == !(ux.i.se & 0x8000)) {
+		ux.i2.lo++;
+		if (ux.i2.lo == 0)
+			ux.i2.hi++;
 	} else {
-		if (ux.bits.mlo == 0) {
-			if (ux.bits.mhi == 0)
-				ux.bits.exp--;
-			ux.bits.mhi--;
-		}
-		ux.bits.mlo--;
+		if (ux.i2.lo == 0)
+			ux.i2.hi--;
+		ux.i2.lo--;
 	}
-	/* raise overflow if ux.value is infinite and x is finite */
-	if (ux.bits.exp == 0x7fff)
+	/* raise overflow if ux is infinite and x is finite */
+	if ((ux.i.se & 0x7fff) == 0x7fff)
 		return x + x;
-	/* raise underflow if ux.value is subnormal or zero */
-	if (ux.bits.exp == 0)
-		FORCE_EVAL(x*x + ux.value*ux.value);
-	return ux.value;
+	/* raise underflow if ux is subnormal or zero */
+	if ((ux.i.se & 0x7fff) == 0)
+		FORCE_EVAL(x*x + ux.f*ux.f);
+	return ux.f;
 }
 #endif