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.

 

Simon

 

From: libraries-bounces@haskell.org [mailto:libraries-bounces@haskell.org] On Behalf Of Levent Erkok
Sent: 10 April 2013 19:25
To: libraries@haskell.org
Subject: Fix prelude definitions of abs/signum for Floats/Doubles

 

The current definition of "abs" and "signum" for the types Float/Double is not IEEE-754 compliant. To wit:

 

   Prelude> abs (-0.0::Float)

   -0.0

   Prelude> signum (-0.0::Float)

   0.0

 

The correct result should be the other way around; abs returning 0.0 and signum returning -0.0 when they receive a negative-zero. The same also holds for the type Double.

 

The issue came up several times in several forums, with general consensus that the behavior should match the IEEE-754 specs. Here're three different discussions on this matter:

 

        http://www.haskell.org/pipermail/libraries/2011-January/015761.html

        http://stackoverflow.com/questions/10395761/absolute-value-of-negative-zero-bug-or-a-part-of-the-floating-point-standard

        http://www.haskell.org/pipermail/haskell-cafe/2013-April/107471.html

 

Proposed fix: Section 6.4.4 of the report http://www.haskell.org/onlinereport/basic.html#sect6.4 gives "default" definitions for abs/signum; which fails to take into account of negative-zero values for floating-point types. An easy fix would be to add to the report a note on the status of negative-zero for Real/Float instances; with individual implementations explicitly checking for negative-0 first. For instance GHC's implementation can be changed as follows:

 

instance Num Float where

    signum x | isNegativeZero x = x

             | x == 0           = 0

             | x > 0.0          = 1

             | otherwise        = negate 1

    abs x    | isNegativeZero x = 0

             | x >= 0           = x

             | otherwise        = negate x

 

A similar change would need to be done for the "Num Double" instance as well. 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.

 

Library guidelines suggest a discussion period of 2 weeks on this issue. I'm hoping that we can resolve the issue in a timely manner, and at least GHC's implementation can match the desired semantics in the next release. If there's consensus at the end of 2-weeks; I'll go ahead and create a corresponding ticket for GHC.

 

Thanks,

 

-Levent.