[GHC] #15926: conversion from Integer to Double rounds differently depending on the value

GHC ghc-devs at haskell.org
Wed Nov 21 00:10:26 UTC 2018


#15926: conversion from Integer to Double rounds differently depending on the value
--------------------------------------+------------------------------------
           Reporter:  drvirgilio      |             Owner:  (none)
               Type:  bug             |            Status:  new
           Priority:  normal          |         Milestone:  Research needed
          Component:  Compiler        |           Version:  8.6.2
           Keywords:                  |  Operating System:  Linux
       Architecture:  x86_64 (amd64)  |   Type of failure:  None/Unknown
          Test Case:                  |        Blocked By:
           Blocking:                  |   Related Tickets:
Differential Rev(s):                  |         Wiki Page:
--------------------------------------+------------------------------------
 I'm not sure if this is intended behavior or a bug.

 For values less than 2^53^, the the Integer can be represented exactly as
 a Double so there is no issue. For values from 2^53^ to 2^63^,
 {{{fromInteger n}}} rounds to the nearest {{{Double}}}, where ties go
 toward the {{{Double}}} with even least significant bit. This matches the
 behavior of {{{read}}}. For values between 2^63^ and 2^1024^,
 {{{fromInteger n}}} ''rounds down'' to the next representable
 {{{Double}}}.

 Steps to reproduce:

 These values are all the same except the last one because it falls just
 below the threshold for the "round to nearest, ties to even" rule. In this
 example, (2^63^) and (2^63^-2^10^) are the consecutive values of type
 {{{Double}}}.

 {{{#!hs
 > fromInteger (2^63) :: Double           -- exactly 9223372036854775808
 9.223372036854776e18
 > fromInteger (2^63 - 1) :: Double       -- rounded up
 9.223372036854776e18
 > fromInteger (2^63 - 2^9) :: Double     -- rounded up
 9.223372036854776e18
 > fromInteger (2^63 - 2^9 - 1) :: Double -- rounded down
 9.223372036854775e18
 > fromInteger (2^63 - 2^10) :: Double    -- exactly 9223372036854774784
 9.223372036854775e18
 }}}

 Here you can see the behavior of {{{fromInteger}}} matches that of {{{read
 . show}}}

 {{{#!hs
 > (read . show) (2^63) :: Double           -- exactly 9223372036854775808
 9.223372036854776e18
 > (read . show) (2^63 - 1) :: Double       -- rounded up
 9.223372036854776e18
 > (read . show) (2^63 - 2^9) :: Double     -- rounded up
 9.223372036854776e18
 > (read . show) (2^63 - 2^9 - 1) :: Double -- rounded down
 9.223372036854775e18
 > (read . show) (2^63 - 2^10) :: Double    -- exactly 9223372036854774784
 9.223372036854775e18
 }}}

 Here you can see {{{fromInteger}}} is rounding down. In this example,
 (2^64^) and (2^64^-2^11^) are the consecutive values of type {{{Double}}}.
 {{{#!hs
 > fromInteger (2^64) :: Double            -- exactly 18446744073709551616
 1.8446744073709552e19
 > fromInteger (2^64 - 1) :: Double        -- rounded down
 1.844674407370955e19
 > fromInteger (2^64 - 2^10) :: Double     -- rounded down
 1.844674407370955e19
 > fromInteger (2^64 - 2^10 - 1) :: Double -- rounded down
 1.844674407370955e19
 > fromInteger (2^64 - 2^11) :: Double     -- exactly 18446744073709549568
 1.844674407370955e19
 }}}

 Here you can see the behavior of {{{fromInteger}}} does ''not'' match the
 behavior of {{{read . show}}}

 {{{#!hs
 > (read . show) (2^64) :: Double            -- exactly
 18446744073709551616
 1.8446744073709552e19
 > (read . show) (2^64 - 1) :: Double        -- rounded up
 1.8446744073709552e19
 > (read . show) (2^64 - 2^10) :: Double     -- rounded up
 1.8446744073709552e19
 > (read . show) (2^64 - 2^10 - 1) :: Double -- rounded down
 1.844674407370955e19
 > (read . show) (2^64 - 2^11) :: Double     -- exactly
 18446744073709549568
 1.844674407370955e19
 }}}

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


More information about the ghc-tickets mailing list