[GHC] #10378: min/max for Double/Float instances are incorrect
GHC
ghc-devs at haskell.org
Mon May 4 05:47:16 UTC 2015
#10378: min/max for Double/Float instances are incorrect
-------------------------------------+-------------------------------------
Reporter: lerkok | Owner:
Type: bug | Status: new
Priority: high | Milestone:
Component: Compiler | Version: 7.10.1
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
Type of failure: None/Unknown | Unknown/Multiple
Blocked By: | Test Case:
Related Tickets: | Blocking:
| Differential Revisions:
-------------------------------------+-------------------------------------
Description changed by lerkok:
Old description:
> 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.
>
> Furthermore, the current definitions are not commutative, when given
> `NaNs` and `-0` arguments.
>
> The following cases demonstrate the issue with `max`. Note that `min` has
> the exact same problems.
>
> {{{#!hs
> Prelude> (0/0) `max` 5
> NaN
> Prelude> 5 `max` (0/0)
> 5.0
> Prelude> isNegativeZero ((-0) `max` 0)
> False
> Prelude> isNegativeZero (0 `max` (-0))
> True
> }}}
>
> It wouldn't be hard to fix the definitions appropriately; here are
> reference implementations that are IEEE754 compliant:
>
> {{{#!hs
> maxH x y
> | isNaN x = y
> | isNaN y = x
> | x > y || (x == y && isNegativeZero y) = x
> | True = y
>
> minH x y
> | isNaN x = y
> | isNaN y = x
> | x < y || (x == y && isNegativeZero x) = x
> | True = y
> }}}
>
> Note that these reference implementations would be quite expensive if GHC
> were to use them directly. Luckily, IEEE754 compliant min/max operations
> are supported by all modern CPUs, so doing the "right" thing here is also
> the cheaper thing as well. (i.e., it'll even be faster than the current
> incorrect implementation.)
>
> On platforms that do not have hardware implementations, the above
> definitions can serve as the correct implementations, albeit they'll be
> slower. (Embedded devices, perhaps.)
New description:
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.
Furthermore, the current definitions are not commutative, when given
`NaNs` and `-0` arguments.
The following cases demonstrate the issue with `max`. Note that `min` has
the exact same problems.
{{{#!hs
Prelude> (0/0) `max` 5
NaN
Prelude> 5 `max` (0/0)
5.0
Prelude> isNegativeZero ((-0) `max` 0)
False
Prelude> isNegativeZero (0 `max` (-0))
True
}}}
It wouldn't be hard to fix the definitions appropriately; here are
reference implementations that are IEEE754 compliant:
{{{#!hs
max x y
| isNaN x = y
| isNaN y = x
| x > y || (x == y && isNegativeZero y) = x
| True = y
min x y
| isNaN x = y
| isNaN y = x
| x < y || (x == y && isNegativeZero x) = x
| True = y
}}}
Note that these reference implementations would be quite expensive if GHC
were to use them directly. Luckily, IEEE754 compliant min/max operations
are supported by all modern CPUs, so doing the "right" thing here is also
the cheaper thing as well. (i.e., it'll even be faster than the current
incorrect implementation.)
On platforms that do not have hardware implementations, the above
definitions can serve as the correct implementations, albeit they'll be
slower. (Embedded devices, perhaps.)
--
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10378#comment:2>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list