Fix prelude definitions of abs/signum for Floats/Doubles

Levent Erkok erkokl at gmail.com
Thu Apr 11 11:50:38 CEST 2013


Great catch! To be IEEE-754 compliant, signum *should* return NaN on NaN.
Here's the new code:

instance Num Float where
    signum x | isNegativeZero x = x
             | isNaN x          = x
             | x == 0           = 0
             | x > 0.0          = 1
             | otherwise        = negate 1
    abs x    | isNegativeZero x = 0
             | x >= 0           = x
             | otherwise        = negate x

Of course, this extra test makes Simon's point even more relevant; i.e.;
these should map to underlying CPU's native signum/abs functions if
available.

-Levent.



On Thu, Apr 11, 2013 at 2:23 AM, Shachaf Ben-Kiki <shachaf at gmail.com> wrote:

> On Wed, Apr 10, 2013 at 11:24 AM, Levent Erkok <erkokl at gmail.com> wrote:
> > 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.
> >
>
> While we're at it: abs NaN is NaN, but signum NaN is currently -1.0.
> Maybe it should also be NaN?
>
>     Shachaf
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/libraries/attachments/20130411/a413d533/attachment-0001.htm>


More information about the Libraries mailing list