Fix prelude definitions of abs/signum for Floats/Doubles

Shachaf Ben-Kiki shachaf at gmail.com
Thu Apr 11 11:32:35 CEST 2013


On Thu, Apr 11, 2013 at 2:19 AM, Twan van Laarhoven <twanvl at gmail.com> wrote:
> 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
>
>

I didn't see Twan's email when I sent my previous one, but relatedly
it should be noted that an unsafeCoerce implementation that doesn't
respect NaNs can allow distinguishing between NaNs, i.e.

    λ> signumDouble (w2d 0xfff8000000000000)
    -1.0
    λ> signumDouble (w2d 0x7ff8000000000000)
    1.0

Possibly this is considered a bad thing.

    Shachaf



More information about the Libraries mailing list