[Haskell-cafe] abs on Float/Doubles

Levent Erkok erkokl at gmail.com
Mon Apr 8 01:21:49 CEST 2013


Hello all,

I definitely do not want to create a yet another thread on handling of
floating-point values in Haskell. My intention is only to see what can be
done to make it more "compilant" with IEEE754. (Also, my interest is not a
theoretical one, but rather entirely practical: I'm interested in using SMT
solvers for reasoning about Haskell programs, in particular using the new
SMT logics that cover IEEE-754 semantics. So, any discrepancy between
Haskell and IEEE-754 is a cause for concern as we strive to
build powerful tools around the Haskell eco-system.)

In IEEE-754, there are two zero values: +0, and -0; inhabiting all floating
point types. IEEE-754 requires these two compare equal, but be
distinguished when used as arguments to functions as they can produce
different results.  (Unfortunately the standard is not freely available,
but there's a nice discussion in wikipedia:
http://en.wikipedia.org/wiki/Negative_zero.)

As far as I know, Haskell's floating-point handling does *not* explicitly
claim to be IEEE-754 compliant, but I think it's safe to assume that any
serious implementation will take advantage of the underlying CPU's
floating-point facilities; and thus will use IEEE-754 semantics. In
particular, Haskell supports both +0 and -0; and you can distinguish them
using the isNegativeZero function of the RealFloat class. Furthermore, the
show instance for Float/Double will turn these two values to strings
differently, preserving the minus sign if it receives a negative-zero.
Comparisons follow the IEEE rules; so all these behaviors seem to be in
accordance with IEEE754.

Unfortunately, the same isn't true for the abs function. In Haskell, the
call: "isNegativeZero (abs (-0::Double))" evaluates to "True". IEEE754
requires abs to always return "+0" in this case. The same also holds for
the semantics of the newly proposed SMT-Lib logic for IEEE754: See section
3.3.1 (page 8) of: http://www.philipp.ruemmer.org/publications/smt-fpa.pdf

The fix is easy. A one line change in the Double/Float instances of the Num
class in the Prelude would guarantee the IEEE754 semantics.

The reason I'm not simply posting this as a "library" issue is that it
appears the topic came up in stack-overflow a while ago; without any clear
resolution:
http://stackoverflow.com/questions/10395761/absolute-value-of-negative-zero-bug-or-a-part-of-the-floating-point-standard

It appears that the consensus is that this is a historical definition
dating back to the times when IEEE754 itself wasn't quite clear on the
topic itself, and "so nobody thought that hard about negative zeroes." (The
quote is from a comment from Lennart.)

I think it's a safe bet to assume IEEE754 semantics (for better or worse)
is here to stay, and it would be nice to reduce any discrepancy we have in
the Haskell libraries with respect to it. So, if there's consensus, I'd
like to propose a library change to implement the proper IEEE754 semantics
for the abs function for Double and Float types.

Note that the argument is not really about semantics here, but rather with
compliance to the accepted industrial standard. So, it would be best if we
kept the discussion purely to the IEEE-compliance here, as opposed to
relative merits of the semantics as defined.

-Levent.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20130407/35d80bb2/attachment.htm>


More information about the Haskell-Cafe mailing list