From 2eee382a62a909d5a3f2f5eda94f30fe68fd5335 Mon Sep 17 00:00:00 2001 From: "kr.angelov" Date: Fri, 20 Jan 2012 13:41:10 +0000 Subject: initial import of the C runtime --- src/runtime/c/gu/bits.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 src/runtime/c/gu/bits.c (limited to 'src/runtime/c/gu/bits.c') diff --git a/src/runtime/c/gu/bits.c b/src/runtime/c/gu/bits.c new file mode 100644 index 000000000..9126b0448 --- /dev/null +++ b/src/runtime/c/gu/bits.c @@ -0,0 +1,53 @@ +#include + +#include +#include +#include +#include +#include +#include + +unsigned gu_ceil2e(unsigned u) +{ + u--; + u |= u >> 1; + u |= u >> 2; + u |= u >> 4; + u |= u >> 8; +#if UINT_MAX > UINT16_MAX + u |= u >> 16; +#endif +#if UINT_MAX > UINT32_MAX + u |= u >> 32; +#endif + u++; + return u; +} + +GU_DEFINE_TYPE(GuIntDecodeExn, abstract, _); + +double +gu_decode_double(uint64_t u) +{ + bool sign = u >> 63; + unsigned rawexp = u >> 52 & 0x7ff; + uint64_t mantissa = u & 0xfffffffffffff; + double ret; + + if (rawexp == 0x7ff) { + if (mantissa == 0) { + ret = INFINITY; + } else { + // At least glibc supports specifying the + // mantissa like this. + int len = snprintf(NULL, 0, "0x%" PRIx64, mantissa); + char buf[len + 1]; + snprintf(buf, len + 1, "0x%" PRIx64, mantissa); + ret = nan(buf); + } + } else { + uint64_t m = rawexp ? 1ULL << 52 | mantissa : mantissa << 1; + ret = ldexp((double) m, rawexp - 1075); + } + return sign ? copysign(ret, -1.0) : ret; +} -- cgit v1.2.3