summaryrefslogtreecommitdiff
path: root/src/runtime/c/gu/bits.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/c/gu/bits.c')
-rw-r--r--src/runtime/c/gu/bits.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/runtime/c/gu/bits.c b/src/runtime/c/gu/bits.c
index 8c43b8477..b5696a19c 100644
--- a/src/runtime/c/gu/bits.c
+++ b/src/runtime/c/gu/bits.c
@@ -41,3 +41,36 @@ gu_decode_double(uint64_t u)
}
return sign ? copysign(ret, -1.0) : ret;
}
+
+GU_INTERNAL uint64_t
+gu_encode_double(double d)
+{
+ int sign = signbit(d) > 0;
+ unsigned rawexp;
+ uint64_t mantissa;
+
+ switch (fpclassify(d)) {
+ case FP_NAN:
+ rawexp = 0x7ff;
+ mantissa = 1;
+ break;
+ case FP_INFINITE:
+ rawexp = 0x7ff;
+ mantissa = 0;
+ break;
+ 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 & 0x7ff) << 52) |
+ mantissa;
+
+ return u;
+}