[Haskell-cafe] Coercion from a Word32/64 to a Float/Double
minh thu
noteed at gmail.com
Mon Sep 14 17:16:20 EDT 2009
2009/9/14 Judah Jacobson <judah.jacobson at gmail.com>:
> On Mon, Sep 14, 2009 at 12:24 PM, minh thu <noteed at gmail.com> wrote:
>> Hi,
>>
>> I'd like to know if this should work:
>>
>> -- GHC coercion
>> getFloat :: BHeader -> Get Float
>> getFloat h =
>> case endianness h of
>> LittleEndian -> fmap (coerce . fromIntegral) getWord32le
>> BigEndian -> fmap (coerce . fromIntegral) getWord32be
>> where coerce (I32# x) = F# (unsafeCoerce# x)
>>
>> -- GHC coercion
>> getDouble :: BHeader -> Get Double
>> getDouble h =
>> case endianness h of
>> LittleEndian -> fmap (coerce . fromIntegral) getWord64le
>> BigEndian -> fmap (coerce . fromIntegral) getWord64be
>> where coerce (I64# x) = D# (unsafeCoerce# x)
>>
>> Loading this into ghci compiles fine (but I haven't try to parse
>> data), but compiling with ghc (6.10.1 or 6.10.4) reports:
>> /tmp/ghc1967_0/ghc1967_0.s: Assembler messages:
>>
>> /tmp/ghc1967_0/ghc1967_0.s:287:0:
>> Error: bad register name `%fake0'
>>
>> /tmp/ghc1967_0/ghc1967_0.s:349:0:
>> Error: bad register name `%fake0'
>
> I think that a more reliable (though not very pretty) way to do the
> casts is via pointer manipulation. Code like the following has worked
> for me in the past:
>
> getDouble :: Get Double
> getDouble = fmap word2Double getWord64le
> where
> word2Double w = unsafePerformIO $ with w $ \p -> do
> d :: CDouble <- peek (castPr p)
> return (realToFrac d :: Double)
>
> Best,
> -Judah
>
Thank you, it compiles fine.
Thu
More information about the Haskell-Cafe
mailing list