2 * Shamelessly lifted from Beej's Guide to Network Programming, found here:
4 * http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html#serialization
6 * Below code was granted to the public domain.
10 uint64_t pack754(long double f, unsigned bits, unsigned expbits)
14 long long sign, exp, significand;
15 unsigned significandbits = bits - expbits - 1; // -1 for sign bit
17 // get this special case out of the way
21 // check sign and begin normalization
30 // get the normalized form of f and track the exponent
32 while (fnorm >= 2.0) {
42 // calculate the binary form (non-float) of the significand data
43 significand = fnorm * ((1LL << significandbits) + 0.5f);
45 // get the biased exponent
46 exp = shift + ((1 << (expbits - 1)) - 1); // shift + bias
48 // return the final answer
49 return (sign << (bits - 1)) | (exp << (bits-expbits - 1)) | significand;
52 long double unpack754(uint64_t i, unsigned bits, unsigned expbits)
57 unsigned significandbits = bits - expbits - 1; // -1 for sign bit
62 // pull the significand
63 result = (i & ((1LL << significandbits) - 1)); // mask
64 result /= (1LL << significandbits); // convert back to float
65 result += 1.0f; // add the one back on
67 // deal with the exponent
68 bias = (1 << (expbits - 1)) - 1;
69 shift = ((i >> significandbits) & ((1LL << expbits) - 1)) - bias;
80 result *= (i >> (bits - 1)) & 1 ? -1.0 : 1.0;