diff options
| author | Krasimir Angelov <kr.angelov@gmail.com> | 2017-09-13 10:23:28 +0200 |
|---|---|---|
| committer | Krasimir Angelov <kr.angelov@gmail.com> | 2017-09-13 10:23:28 +0200 |
| commit | df992c31fdf191c88a5f8cd5ac462e5537523316 (patch) | |
| tree | 1a2550952101cd577c5332f201b6405c14932d74 /src/runtime/c/gu/bits.c | |
| parent | 3e55aa442452d6a38a67466cb2ef30e1ce736bb5 (diff) | |
added gu_out_u16be, gu_out_u64be and gu_out_f64be in libgu. The later is using gu_encode_double which is probably still wrong. Corrected gu_in_le and gu_in_f64be.
Diffstat (limited to 'src/runtime/c/gu/bits.c')
| -rw-r--r-- | src/runtime/c/gu/bits.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/src/runtime/c/gu/bits.c b/src/runtime/c/gu/bits.c index 8c43b8477..21ef71246 100644 --- a/src/runtime/c/gu/bits.c +++ b/src/runtime/c/gu/bits.c @@ -41,3 +41,31 @@ gu_decode_double(uint64_t u) } return sign ? copysign(ret, -1.0) : ret; } + +GU_INTERNAL uint64_t +gu_encode_double(double d) +{ + int sign = (d < 0) ? 1 : 0; + int rawexp; + double mantissa; + + switch (fpclassify(d)) { + case FP_NAN: + rawexp = 0x7ff; + mantissa = 1; + break; + case FP_INFINITE: + rawexp = 0x7ff; + mantissa = 0; + break; + default: + mantissa = frexp(d, &rawexp); + rawexp += 1075; + } + + uint64_t u = (((uint64_t) sign) << 63) | + ((((uint64_t) rawexp) << 52) & 0x7ff) | + ((uint64_t) mantissa); + + return u; +} |
