diff options
author | Szabolcs Nagy <nsz@port70.net> | 2013-09-03 04:09:12 +0000 |
---|---|---|
committer | Szabolcs Nagy <nsz@port70.net> | 2013-09-05 11:30:07 +0000 |
commit | ee2ee92d62c43f6658d37ddea4c316d2089d0fe9 (patch) | |
tree | 1a3e5a63fd40fa763f87d5dd9efd021117ea1d11 /src/math/modf.c | |
parent | d1a2ead878c27ac4ec600740320f8b76e1f961e9 (diff) | |
download | musl-ee2ee92d62c43f6658d37ddea4c316d2089d0fe9.tar.gz musl-ee2ee92d62c43f6658d37ddea4c316d2089d0fe9.tar.bz2 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.c | 31 |
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; } |