Reputation: 3244
I have a file with binary data (more precisely, it's a npy file = header data + raw binary data). This data ([0.1, 0.2, 0.3, 0.4] for tests) can be successfully readed by this code in C++ (skipped):
int word_size = 8;
double *data;
arr = new char[size*word_size];
size_t nread = fread(arr, word_size, size, file);
if(nread != size)
*data = reinterpret_cast<double *>(arr);
I'm trying to implement this in Haskell:
data Header = Header {
{- other fields -}
npyData :: [Double]
} deriving (Show)
getNpyData = do
empty <- isEmpty
if empty
then return []
else do
v <- getWord64be
rest <- getNpyData
return (fromIntegral v : rest)
npyHeader :: Get Header
npyHeader = do
{-other fields -}
npyData <- getNpyData
return Header {
{- other fields -}
npyData=npyData
}
main = do
file <- openBinaryFile "test.npy" ReadMode
input <- BL.hGetContents file
let npyParsedData = runGet npyHeader input
print $ npyData npyParsedData
This gives to me incorrect results for npyData
(other variables are ok):
[1.1140104038263667e19,1.114010403826367e19,3.6893488147419515e18,1.1140104038263675e19]
Can anybody tell me, what is wrong in this code?
Upvotes: 0
Views: 326
Reputation: 2796
Unfortunately, what should work
v <- get :: Double
doesn't since Data.Binary
doesn't use an IEEE754 encoding of doubles (it stores the result of decodeFloat
). Hence a good choice is to use the cereal package. At least within GHC I've gotten unsafeCoerce
on a Word64
to work for similar tasks as well.
bitsToDouble :: Word64 -> Double
bitsToDouble = unsafeCoerce
Probably cereal
is a safer way of doing this.
Upvotes: 1