8 Apr 2013 01:21
abs on Float/Doubles
Levent Erkok <erkokl <at> gmail.com>
2013-04-07 23:21:49 GMT
2013-04-07 23:21:49 GMT
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.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe <at> haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe