about summary refs log tree commit diff
path: root/src/math/modf.c
diff options
context:
space:
mode:
authorSzabolcs Nagy <nsz@port70.net>2013-09-03 04:09:12 +0000
committerSzabolcs Nagy <nsz@port70.net>2013-09-05 11:30:07 +0000
commitee2ee92d62c43f6658d37ddea4c316d2089d0fe9 (patch)
tree1a3e5a63fd40fa763f87d5dd9efd021117ea1d11 /src/math/modf.c
parentd1a2ead878c27ac4ec600740320f8b76e1f961e9 (diff)
downloadmusl-ee2ee92d62c43f6658d37ddea4c316d2089d0fe9.tar.gz
musl-ee2ee92d62c43f6658d37ddea4c316d2089d0fe9.tar.xz
musl-ee2ee92d62c43f6658d37ddea4c316d2089d0fe9.zip
math: rewrite remainder functions (remainder, remquo, fmod, modf)
* results are exact
* modfl follows truncl (raises inexact flag spuriously now)
* modf and modff only had cosmetic cleanup
* remainder is just a wrapper around remquo now
* using iterative shift+subtract for remquo and fmod
* ld80 and ld128 are supported as well
Diffstat (limited to 'src/math/modf.c')
-rw-r--r--src/math/modf.c31
1 files changed, 14 insertions, 17 deletions
diff --git a/src/math/modf.c b/src/math/modf.c
index 8f337ef0..1c8a1db9 100644
--- a/src/math/modf.c
+++ b/src/math/modf.c
@@ -2,36 +2,33 @@
 
 double modf(double x, double *iptr)
 {
-	union {double x; uint64_t n;} u = {x};
+	union {double f; uint64_t i;} u = {x};
 	uint64_t mask;
-	int e;
-
-	e = (int)(u.n>>52 & 0x7ff) - 0x3ff;
+	int e = (int)(u.i>>52 & 0x7ff) - 0x3ff;
 
 	/* no fractional part */
 	if (e >= 52) {
 		*iptr = x;
-		if (e == 0x400 && u.n<<12 != 0) /* nan */
+		if (e == 0x400 && u.i<<12 != 0) /* nan */
 			return x;
-		u.n &= (uint64_t)1<<63;
-		return u.x;
+		u.i &= 1ULL<<63;
+		return u.f;
 	}
 
 	/* no integral part*/
 	if (e < 0) {
-		u.n &= (uint64_t)1<<63;
-		*iptr = u.x;
+		u.i &= 1ULL<<63;
+		*iptr = u.f;
 		return x;
 	}
 
-	mask = (uint64_t)-1>>12 >> e;
-	if ((u.n & mask) == 0) {
+	mask = -1ULL>>12>>e;
+	if ((u.i & mask) == 0) {
 		*iptr = x;
-		u.n &= (uint64_t)1<<63;
-		return u.x;
+		u.i &= 1ULL<<63;
+		return u.f;
 	}
-	u.n &= ~mask;
-	*iptr = u.x;
-	STRICT_ASSIGN(double, x, x - *iptr);
-	return x;
+	u.i &= ~mask;
+	*iptr = u.f;
+	return x - u.f;
 }