summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKrasimir Angelov <kr.angelov@gmail.com>2017-09-13 17:20:00 +0200
committerKrasimir Angelov <kr.angelov@gmail.com>2017-09-13 17:20:00 +0200
commit1ff8dd88e8df65f635962c30cb9bc7f37dbd81aa (patch)
treebfb5bec3c80b3a16ac75619ba81515c219547d2e /src
parentfebf01a9bec6043ca0c988fcc91126b0b6e60d51 (diff)
fix gu_encode_double
Diffstat (limited to 'src')
-rw-r--r--src/runtime/c/gu/bits.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/src/runtime/c/gu/bits.c b/src/runtime/c/gu/bits.c
index 21ef71246..b5696a19c 100644
--- a/src/runtime/c/gu/bits.c
+++ b/src/runtime/c/gu/bits.c
@@ -45,9 +45,9 @@ gu_decode_double(uint64_t u)
GU_INTERNAL uint64_t
gu_encode_double(double d)
{
- int sign = (d < 0) ? 1 : 0;
- int rawexp;
- double mantissa;
+ int sign = signbit(d) > 0;
+ unsigned rawexp;
+ uint64_t mantissa;
switch (fpclassify(d)) {
case FP_NAN:
@@ -58,14 +58,19 @@ gu_encode_double(double d)
rawexp = 0x7ff;
mantissa = 0;
break;
- default:
- mantissa = frexp(d, &rawexp);
- rawexp += 1075;
+ default: {
+ int exp;
+ mantissa = (uint64_t) scalbn(frexp(d, &exp), 53);
+ mantissa &= ~ (1ULL << 52);
+ exp -= 53;
+
+ rawexp = exp + 1075;
+ }
}
uint64_t u = (((uint64_t) sign) << 63) |
- ((((uint64_t) rawexp) << 52) & 0x7ff) |
- ((uint64_t) mantissa);
+ (((uint64_t) rawexp & 0x7ff) << 52) |
+ mantissa;
return u;
}