New patches: [Add putFloat[32|64][be|le] for serialising IEEE floating point numbers agl@imperialviolet.org**20070820185237] { hunk ./src/Data/Binary/Builder.hs 10 --- +-- hunk ./src/Data/Binary/Builder.hs 44 + , putFloat32be -- :: Float -> Builder + , putFloat64be -- :: Double -> Builder hunk ./src/Data/Binary/Builder.hs 51 + , putFloat32le -- :: Float -> Builder + , putFloat64le -- :: Double -> Builder hunk ./src/Data/Binary/Builder.hs 59 - hunk ./src/Data/Binary/Builder.hs 62 +import Foreign.C.Types (CFloat, CDouble) hunk ./src/Data/Binary/Builder.hs 381 +------------------------------------------------------------------------ +-- IEEE floating point ops + +-- This is a little bit dodgy, standards-wise, since I don't know if the C +-- standard actually says that a float is an IEEE single-precision, nor if a +-- double is a double-precision. + +putFloat32be :: Float -> Builder +putFloat32be f = writeN 4 (\p -> do + let cf :: CFloat + cf = fromRational $ toRational f + -- We poke and peek to get the float as a Word32 and then use the same code + -- as above to write it out in BE order + poke (castPtr p) cf + w <- peek (castPtr p) :: IO Word32 + poke p (fromIntegral (shiftr_w32 w 24) :: Word8) + poke (p `plusPtr` 1) (fromIntegral (shiftr_w32 w 16) :: Word8) + poke (p `plusPtr` 2) (fromIntegral (shiftr_w32 w 8) :: Word8) + poke (p `plusPtr` 3) (fromIntegral (w) :: Word8)) + +putFloat32le :: Float -> Builder +putFloat32le f = writeN 4 (\p -> do + let cf :: CFloat + cf = fromRational $ toRational f + -- We poke and peek to get the float as a Word32 and then use the same code + -- as above to write it out in LE order + poke (castPtr p) cf + w <- peek (castPtr p) :: IO Word32 + poke p (fromIntegral (w) :: Word8) + poke (p `plusPtr` 1) (fromIntegral (shiftr_w32 w 8) :: Word8) + poke (p `plusPtr` 2) (fromIntegral (shiftr_w32 w 16) :: Word8) + poke (p `plusPtr` 3) (fromIntegral (shiftr_w32 w 24) :: Word8)) + +putFloat64be :: Double -> Builder +putFloat64be d = writeN 8 (\p -> do + let cd :: CDouble + cd = fromRational $ toRational d + -- Even if the CPU has 80-bit floats (i.e. x86 before compilers started using + -- SEE for floating point computation), the external format will still be + -- 64-bit + poke (castPtr p) cd + w <- peek (castPtr p) :: IO Word64 + poke p (fromIntegral (shiftr_w64 w 56) :: Word8) + poke (p `plusPtr` 1) (fromIntegral (shiftr_w64 w 48) :: Word8) + poke (p `plusPtr` 2) (fromIntegral (shiftr_w64 w 40) :: Word8) + poke (p `plusPtr` 3) (fromIntegral (shiftr_w64 w 32) :: Word8) + poke (p `plusPtr` 4) (fromIntegral (shiftr_w64 w 24) :: Word8) + poke (p `plusPtr` 5) (fromIntegral (shiftr_w64 w 16) :: Word8) + poke (p `plusPtr` 6) (fromIntegral (shiftr_w64 w 8) :: Word8) + poke (p `plusPtr` 7) (fromIntegral (w) :: Word8)) + +putFloat64le :: Double -> Builder +putFloat64le d = writeN 8 (\p -> do + let cd :: CDouble + cd = fromRational $ toRational d + -- Even if the CPU has 80-bit floats (i.e. x86 before compilers started using + -- SEE for floating point computation), the external format will still be + -- 64-bit + poke (castPtr p) cd + w <- peek (castPtr p) :: IO Word64 + poke p (fromIntegral (w) :: Word8) + poke (p `plusPtr` 1) (fromIntegral (shiftr_w64 w 8) :: Word8) + poke (p `plusPtr` 2) (fromIntegral (shiftr_w64 w 16) :: Word8) + poke (p `plusPtr` 3) (fromIntegral (shiftr_w64 w 24) :: Word8) + poke (p `plusPtr` 4) (fromIntegral (shiftr_w64 w 32) :: Word8) + poke (p `plusPtr` 5) (fromIntegral (shiftr_w64 w 40) :: Word8) + poke (p `plusPtr` 6) (fromIntegral (shiftr_w64 w 48) :: Word8) + poke (p `plusPtr` 7) (fromIntegral (shiftr_w64 w 56) :: Word8)) + hunk ./src/Data/Binary/Put.hs 34 + , putFloat32be + , putFloat64be hunk ./src/Data/Binary/Put.hs 41 + , putFloat32le + , putFloat64le hunk ./src/Data/Binary/Put.hs 140 +-- | Write an IEEE 32-bit float in big-endian format +putFloat32be :: Float -> Put +putFloat32be = tell . B.putFloat32be + +-- | Write an IEEE 64-bit float in big-endian format +putFloat64be :: Double -> Put +putFloat64be = tell . B.putFloat64be + +-- | Write an IEEE 32-bit float in little-endian format +putFloat32le :: Float -> Put +putFloat32le = tell . B.putFloat32le + +-- | Write an IEEE 64-bit float in little-endian format +putFloat64le :: Double -> Put +putFloat64le = tell . B.putFloat64le + } Context: [Don't rely on the [a] instance in Array serialization Spencer Janssen **20070711031747] [comment the more efficient Array serialisation Don Stewart **20070711030251] [Attempt to avoid expensive 'length' call in array serialization Spencer Janssen **20070711025531] [unsafePerformIO in alloc code Don Stewart **20070615040919] [Switch to control flow Lennart Kolmodin **20070606084057] [Add feature to check that tests fail Lennart Kolmodin **20070606084030] [Fix a segfault in Data.Binary.Get. tup **20070404125154 "runGet getWord8 empty" segfaulted due to the absence of a length check in getPtr. This patch also forces the evaluation of a possible exceptional value in getBytes. ] [Test to read too much Lennart Kolmodin **20070606065544] [Add MonadFix instance for the Get monad. Judah Jacobson **20070425030304] [TAG 0.3 Lennart Kolmodin **20070327200247] Patch bundle hash: 8735f1b747c62868331c24268a41605390d288f9