rbtree.c smalloc.c filehash.c profile.c debug.c lib/rand.c \
lib/num2str.c $(wildcard crc/*.c) engines/cpu.c \
engines/mmap.c engines/sync.c engines/null.c engines/net.c \
- memalign.c server.c client.c iolog.c
+ memalign.c server.c client.c iolog.c ieee754.c
ifeq ($(UNAME), Linux)
SOURCE += diskutil.c fifo.c blktrace.c helpers.c cgroup.c trim.c \
--- /dev/null
+/*
+ * Shamelessly lifted from Beej's Guide to Network Programming, found here:
+ *
+ * http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html#serialization
+ *
+ * Below code was granted to the public domain.
+ */
+#include <inttypes.h>
+
+uint64_t pack754(long double f, unsigned bits, unsigned expbits)
+{
+ long double fnorm;
+ int shift;
+ long long sign, exp, significand;
+ unsigned significandbits = bits - expbits - 1; // -1 for sign bit
+
+ // get this special case out of the way
+ if (f == 0.0)
+ return 0;
+
+ // check sign and begin normalization
+ if (f < 0) {
+ sign = 1;
+ fnorm = -f;
+ } else {
+ sign = 0;
+ fnorm = f;
+ }
+
+ // get the normalized form of f and track the exponent
+ shift = 0;
+ while (fnorm >= 2.0) {
+ fnorm /= 2.0;
+ shift++;
+ }
+ while (fnorm < 1.0) {
+ fnorm *= 2.0;
+ shift--;
+ }
+ fnorm = fnorm - 1.0;
+
+ // calculate the binary form (non-float) of the significand data
+ significand = fnorm * ((1LL << significandbits) + 0.5f);
+
+ // get the biased exponent
+ exp = shift + ((1 << (expbits - 1)) - 1); // shift + bias
+
+ // return the final answer
+ return (sign << (bits - 1)) | (exp << (bits-expbits - 1)) | significand;
+}
+
+long double unpack754(uint64_t i, unsigned bits, unsigned expbits)
+{
+ long double result;
+ long long shift;
+ unsigned bias;
+ unsigned significandbits = bits - expbits - 1; // -1 for sign bit
+
+ if (i == 0)
+ return 0.0;
+
+ // pull the significand
+ result = (i & ((1LL << significandbits) - 1)); // mask
+ result /= (1LL << significandbits); // convert back to float
+ result += 1.0f; // add the one back on
+
+ // deal with the exponent
+ bias = (1 << (expbits - 1)) - 1;
+ shift = ((i >> significandbits) & ((1LL << expbits) - 1)) - bias;
+ while (shift > 0) {
+ result *= 2.0;
+ shift--;
+ }
+ while (shift < 0) {
+ result /= 2.0;
+ shift++;
+ }
+
+ // sign it
+ result *= (i >> (bits - 1)) & 1 ? -1.0 : 1.0;
+
+ return result;
+}
--- /dev/null
+#ifndef FIO_IEEE754_H
+#define FIO_IEEE754_H
+
+extern uint64_t pack754(long double f, unsigned bits, unsigned expbits);
+extern long double unpack754(uint64_t i, unsigned bits, unsigned expbits);
+
+#define fio_double_to_uint64(val) pack754((val), 64, 11)
+#define fio_uint64_to_double(val) unpack754((val), 64, 11)
+
+#endif