Re: [Haskell] How to get the binary respentation of the Int/Double.

Actually, this is a good question, at least as relating to floating point values. Is there a primitive to view the machine representation of floats? I'm thinking of functions like: reinterpretFloatAsWord :: Float -> Word32 reinterpretWordAsFloat :: Word32 -> Float reinterpretDoubleAsWord :: Double -> Word64 reinterpretWordAsDouble :: Word64 -> Double There are decodeFloat and encodeFloat in the RealFloat class, but these seem to be a bit heavy for inner-loop usage, especially when you are just going to paste the values back together into a word immediately anyways. Are the precision of Float and Double specified by the standard? There's actually lots of nice tricks you can do with these functions; for example, if you know you have a floating point value between 0 and 2^23-1, you can convert it to integer with a floating point add and an integer mask:
magic = 0x00800000 :: Float -- 2^23 magicMask = 0x007fffff :: Word32 -- 2^23 - 1
fastFloatToInt23 :: Float -> Word32 fastFloatToInt23 x = reinterpretFloatAsWord (x + magic) .&. magicMask
The add sets the exponent of the float to +23 and arranges it so the
low bit of the float corresponds to "1", rounding if necessary. Then
you can interpret the result as an integer and mask off the exponent
and sign bit from the float, leaving you with just the integer value.
This relies on the representation of IEEE single-precision floats, of
course.
These sorts of tricks come have in handy when working on graphics
code; often I've found myself wanting to index into an array with the
nearest value after some floating point computation. Texture mapping
hardware does this conversion all the time, for example, and sometimes
it's useful to emulate that behavior in software.
-- ryan
On Tue, Oct 28, 2008 at 10:08 AM, Brandon S. Allbery KF8NH
On 2008 Oct 28, at 10:38, haihualin wrote:
I am wondering how to get the binary respentation of the Int/Double. So I can save the integer as the binary data so that the C program can read it from the file.
The Binary package on Hackage (http://hackage.haskell.org) allows you to serialize Haskell data in any form including C-compatible binary output.
-- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH
_______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell

Ryan Ingram
Actually, this is a good question, at least as relating to floating point values. Is there a primitive to view the machine representation of floats?
Not a primitive, but it can be defined: module Cast (cast) where import Foreign.Storable (Storable, sizeOf, peek) import Foreign.Marshal.Utils (with) import System.IO.Unsafe (unsafePerformIO) import Foreign.Ptr (castPtr) cast :: (Storable a, Storable b) => a -> b cast a = b where b | sizeOf a == sizeOf b = unsafePerformIO $ with a $ peek . castPtr -- Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig Don't mess with me lady; I've been drinking with skeletons.

On Wed, Oct 29, 2008 at 7:58 PM, Ryan Ingram
Actually, this is a good question, at least as relating to floating point values. Is there a primitive to view the machine representation of floats?
This isn't the first time this issue has come up on this mailing list. I think it would be good if there was a wiki page for this.
participants (3)
-
Bit Connor
-
Chung-chieh Shan
-
Ryan Ingram