Fix prelude definitions of abs/signum for Floats/Doubles

Twan van Laarhoven twanvl at gmail.com
Thu Apr 11 11:19:21 CEST 2013


On 11/04/13 10:24, Simon Peyton-Jones wrote:
> Sounds good to me.
>
> It would be fantastic if someone could investigate Levent’s suggestion “Of
> course, implementations can take advantage of the underlying CPU's native
> floating-point abs/sign functions if available as well, avoiding explicit tests
> at the Haskell code; based on the underlying platform”
>
> Otherwise we’ll just end up adding an extra test and everyone’s code will run a
> little bit slower.

For IEEE floating point numbers, the sign is stored as a single bit, which can 
be changed with simple bit twiddling:

     import Data.Bits
     import Data.Word
     import Unsafe.Coerce

     w2f x = unsafeCoerce (x :: Word32) :: Float
     f2w x = unsafeCoerce (x :: Float) :: Word32
     absFloat = w2f . (`clearBit` 31) . f2w
     signumFloat = w2f . (.|. 0x3f800000) . (.&. 0x80000000) . f2w

     w2d x = unsafeCoerce (x :: Word64) :: Double
     d2w x = unsafeCoerce (x :: Double) :: Word64
     absDouble = w2d . (`clearBit` 63) . d2w
     signumDouble = w2d . (.|. 0x3ff0000000000000) . (.&. 0x8000000000000000) . d2w

(Tested on linux x86-64)


Twan




More information about the Libraries mailing list