]> git.tdb.fi Git - libs/datafile.git/blobdiff - source/binfloat.h
Use custom encoding for floats in binary format
[libs/datafile.git] / source / binfloat.h
diff --git a/source/binfloat.h b/source/binfloat.h
new file mode 100644 (file)
index 0000000..d16570f
--- /dev/null
@@ -0,0 +1,63 @@
+#ifndef MSP_DATAFILE_BINFLOAT_H_
+#define MSP_DATAFILE_BINFLOAT_H_
+
+#include "type.h"
+
+namespace Msp {
+namespace DataFile {
+
+/**
+Facilitates splitting floating-point numbers into parts and putting them back
+together.  Supports arbitary sizes up to 64 bits.  The 16, 32 and 64 bit
+formats exactly match those defined by ISO/IEC 60559:2011.
+
+The exponent is stored in an unbiased form.  The mantissa is stored with the
+integer part included, aligned to the high bits of a 64-bit integer.
+*/
+struct BinFloat
+{
+       struct Bits
+       {
+               unsigned exponent;
+               unsigned mantissa;
+
+               Bits(unsigned);
+       };
+
+       template<typename T>
+       union Conversion
+       {
+               T f;
+               typename MatchingInt<T>::UnsignedType i;
+       };
+
+       bool sign;
+       bool infinity;
+       int exponent;
+       UInt64 mantissa;
+
+       static BinFloat explode(UInt64, const Bits &);
+
+       template<typename T>
+       static BinFloat explode_iec559(T v)
+       {
+               Conversion<T> c;
+               c.f = v;
+               return explode(c.i, sizeof(T)*CHAR_BIT);
+       }
+
+       UInt64 compose(const Bits &);
+
+       template<typename T>
+       T compose_iec559()
+       {
+               Conversion<T> c;
+               c.i = compose(sizeof(T)*CHAR_BIT);
+               return c.f;
+       }
+};
+
+} // namespace DataFile
+} // namespace Msp
+
+#endif