I have a file containing a [Double] serialized by Data.Binary that I'd like to read with C. That is, I want to write a C program that reads that data into memory as double[]. I'm planning on writing a Haskell program to deserialize the data file and then write the binary data into a new, simpler file that I can just directly read into C, but I'm not sure how to write out just the raw binary data (e.g. 8 bytes for a double).
You can reuse Data.Binary for the purpose with the data-binary-ieee754 package, which allows serialising Floats and Doubles as their IEEE representation. For example:
import Data.List
import Data.Binary.Put
import Data.Binary.IEEE754
import Control.Monad
putRawDoubles :: [Double] -> Put
putRawDoubles xs = do
putWord64le $ genericLength xs
mapM_ putFloat64le xs
It would be nice if there was an analogue of putWord64host for Doubles in data-binary-ieee754, but since there isn't I just went with little-endian. If you want to be portable across endiannesses without explicitly handling the conversion in your C program, you could try putWord64host . doubleToWord (doubleToWord is also from Data.Binary.IEEE754). Though I think that integer endianness differs from floating-point endianness on some platforms...
Incidentally, I would suggest using a format like this even for your regular serialisation; IEEE floats are universal, and binary's default floating-point format is wasteful (as Daniel Fischer points out).
You might also want to consider the cereal serialisation library, which is faster than binary, better-maintained (binary hasn't been updated since 2009) and has IEEE float format support built-in.
Using Data.Binary to serialize Double or Float values is not great for portability. The Binary instances serialize the values in the form obtained by decodeFloat, i.e. as a mantissa and an exponent. The mantissa is serialized as an Integer. Parsing that is inconvenient. Much better, as has already suggested by ehird, is using a variant that serializes them as the bit-pattern of the IEEE-754 representation, as offered by cereal-ieee754 - as ehird reminded me, that has been merged (minus some conversion between floating point and word types) into cereal - or the already mentioned data-binary-ieee754. Another option is serializing them as strings via show. That has the advantage of avoiding any endianness problems.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With