# [Haskell-cafe] Proper Handling of Exceptional IEEE Floating Point Numbers

Roman Leshchinskiy rl at cse.unsw.edu.au
Sat Apr 24 08:42:07 EDT 2010

```On 24/04/2010, at 22:06, Barak A. Pearlmutter wrote:

> Currently the standard prelude has default definition:
>
>    ...
>    compare x y
>         | x == y    =  EQ
>         | x <= y    =  LT
>         | otherwise =  GT
>
> I'd suggest
>
> [...]
>
>    compare x y
>         | x < y     =  LT
>         | x == y    =  EQ
> 	 | x > y     =  GT
>         | otherwise =  error "no consistent ordering"
>
> It is not clear to me that this would cause a measurable performance
> hit in the case of floating point numbers.  We're talking about at
> most two extra instructions: a compare and a conditional branch.  The

The problem are not so much the additional instructions. Rather, it's the fact that compare for Float and Double can fail at all which inhibits some optimisations. For instance, GHC is free to eliminate the comparison in (x `compare` y) `seq` a but wouldn't be with your change. It doesn't actually do that at the moment, which looks like an optimiser deficiency to me. But in any case, the property "can fail" has a significant effect on optimisations sometimes.

>> I was thinking of this:
>
>> data T = T Double deriving ( Eq, Ord )
>
>> ... GHC basically produces
>
>> instance Ord T where
>>  compare (T x) (T y) = compare x y
>>  t < u = compare t u == LT
>
> That is indeed what it does.  Which is a plain old bug, since it leads
> to inconsistent behaviour between wrapped vs unwrapped values.
>
> *Main> T (0/0) == T (0/0)
> False
> *Main> T (0/0) < T (0/0)
> False
> *Main> T (0/0) > T (0/0)
> True
> *Main> (0/0) > (0/0)
> False

Urgh. You're right, I hadn't thought of this. Would you care to submit a bug report?

Roman

```