Restore exact old semantics of `decodeFloat`
ClosedPublic

Authored by hvr on Nov 18 2014, 1:39 AM.

Details

Summary

integer-gmp2 uses a new 64bit-based primop
introduced in b62bd5ecf3be421778e4835010b6b334e95c5a56.

However, the returned values differ for exceptional IEEE values:

Previous (expected) semantics:

> decodeFloat (-1/0)
(-4503599627370496,972)

> decodeFloat (1/0)
(4503599627370496,972)

> decodeFloat (0/0)
(-6755399441055744,972)

Currently (broken) semantics:

> decodeFloat (-1/0 :: Double)
(-9223372036854775808,-53)

> decodeFloat (1/0 :: Double)
(-9223372036854775808,-53)

> decodeFloat (0/0 :: Double)
(-9223372036854775808,-53)

This patch reverts to the old expected semantics.

We'll revisit the implementation during GHC 7.11 development.

This should address Trac #9810

Diff Detail

Repository
rGHC Glasgow Haskell Compiler
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.
hvr updated this revision to Diff 1483.Nov 18 2014, 1:39 AM
hvr retitled this revision from to Restore exact old semantics of `decodeFloat`.
hvr updated this object.
hvr edited the test plan for this revision. (Show Details)
hvr added reviewers: luite, rwbarton, ekmett.
hvr updated the Trac tickets for this revision.
hvr added a comment.EditedNov 18 2014, 2:59 AM

Here's some interesting semantics of NaN:

> let dumpIEEE x = putStrLn $ "0x" ++ showHex (unsafeCoerce# (x::Double) :: Word64) ""

> dumpIEEE (1/0)
0x7ff0000000000000
> dumpIEEE (-1/0)
0xfff0000000000000
> dumpIEEE (0/0)
0xfff8000000000000
> dumpIEEE (-0/0)
0x7ff8000000000000

> decodeFloat (0/0 :: Double)
(-6755399441055744,972)

> decodeFloat (-0/0 :: Double)
(6755399441055744,972)

Note how 0/0 has a negative sign (while -0/0 is a positive signed NaN) above, however:

> signum (0/0 :: Double)
-1.0
> signum (-0/0 :: Double)
-1.0

This makes we wonder whether

  1. 0/0 shouldn't rather be positive (and -0/0 be negative), and
  2. the following shall hold: signum (0/0) == 1 and signum (-0/0) == -1, as well as
  3. signum (abs x) == 1 and signum (negate x) == negate (signum x) for x in {0/0, -0/0}.
rwbarton edited edge metadata.Nov 18 2014, 9:02 AM
In D486#12484, @hvr wrote:

Note how 0/0 has a negative sign (while -0/0 is a positive signed NaN) above, however:

> signum (0/0 :: Double)
 -1.0
> signum (-0/0 :: Double)
 -1.0

This makes we wonder whether

  1. 0/0 shouldn't rather be positive (and -0/0 be negative), and
  2. the following shall hold: signum (0/0) == 1 and signum (-0/0) == -1, as well as
  3. signum (abs x) == 1 and signum (negate x) == negate (signum x) for x in {0/0, -0/0}.

Were you testing with HEAD or 7.8? I thought we fixed this in Trac #7858 (defining signum of NaN to be NaN).

hvr added a comment.Nov 18 2014, 9:39 AM

Were you testing with HEAD or 7.8? I thought we fixed this in Trac #7858 (defining signum of NaN to be NaN).

oh... ok, (fixed) GHC HEAD does this btw (it does indeed pass-thru NaN, including its sign):

> decodeFloat (signum (-0/0))
(6755399441055744,972)

> decodeFloat (signum (0/0))
(-6755399441055744,972)
austin accepted this revision.Nov 18 2014, 12:03 PM
austin edited edge metadata.

LGTM.

This revision is now accepted and ready to land.Nov 18 2014, 12:03 PM
ekmett accepted this revision.Nov 18 2014, 12:50 PM
ekmett edited edge metadata.

LGTM

hrm, how come on my 7.8.3 ghci i'm seeing the the following

Prelude> decodeFloat (signum (-0/0 :: Double))
(-4503599627370496,-52)
Prelude> decodeFloat (signum (0/0 :: Double))
(-4503599627370496,-52)
luite accepted this revision.Nov 18 2014, 2:00 PM
luite edited edge metadata.

yep

Let's also add a test that fromRational (toRational x) == x for x <- [1/0, -1/0], since GHC depends on it.

hvr added a comment.Nov 19 2014, 4:08 AM
In D486#12701, @carter wrote:

hrm, how come on my 7.8.3 ghci i'm seeing the the following

Prelude> decodeFloat (signum (-0/0 :: Double))
(-4503599627370496,-52)
Prelude> decodeFloat (signum (0/0 :: Double))
(-4503599627370496,-52)

because you're effectively evaluating decodeFloat (-1.0 :: Double)

hvr updated this revision to Diff 1544.Nov 19 2014, 4:38 AM
hvr edited edge metadata.

rebase & testcase

This revision was automatically updated to reflect the committed changes.