min/max for Double/Float instances are incorrect
This is similar to many other numeric issues around Double
s and Float
s.
The IEEE754 requires min
and max
on floats to return the "other" number, if one of the arguments is NaN
. The default definitions used in Haskell do not satisfy this property.
Unfortunately, the IEEE-spec isn't exactly clear on how min/max should work around +0/-0. It's deliberately underspecified. Most Intel implementations simply return the second argument in this case. So, the following would be the "reference" implementation, assuming we map to the Intel CPU instructions for floating-point min/max:
max x y
| isNaN x = y
| isNaN y = x
| (x == 0) && (y == 0) = y -- takes care of +/-0
| x > y = x
| True = y
min x y
| isNaN x = y
| isNaN y = x
| (x == 0) && (y == 0) = y -- takes care of +/-0
| x < y = x
| True = y