[GHC] #10378: min/max for Double/Float instances are incorrect

GHC ghc-devs at haskell.org
Mon May 4 05:45:37 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
              Keywords:              |  Operating System:  Unknown/Multiple
          Architecture:              |   Type of failure:  None/Unknown
  Unknown/Multiple                   |        Blocked By:
             Test Case:              |   Related Tickets:
              Blocking:              |
Differential Revisions:              |
-------------------------------------+-------------------------------------
 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 does 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`, but `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.)

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10378>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list