[GHC] #15081: Finite list becomes infinite after maping fractional function for high numbers

GHC ghc-devs at haskell.org
Tue Aug 21 14:38:07 UTC 2018


#15081: Finite list becomes infinite after maping fractional function for high
numbers
-------------------------------------+-------------------------------------
        Reporter:  Onsed             |                Owner:  (none)
            Type:  bug               |               Status:  patch
        Priority:  normal            |            Milestone:  8.8.1
       Component:  Compiler          |              Version:  8.2.2
      Resolution:                    |             Keywords:
Operating System:  Linux             |         Architecture:  x86_64
                                     |  (amd64)
 Type of failure:  Incorrect result  |            Test Case:
  at runtime                         |  libraries/base/tests/enumNumeric
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):  Phab:D4650
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by sighingnow):

 @thomie Thanks for your program in comment:11. However I think we have no
 way to improve the situation further.

 The double number `9007199254740992` and `9007199254740993` have same
 binary representation. You could check this problem with the following
 program.

 {{{#!cpp
 #include <stdio.h>
 #include <stdint.h>

 union double_uint64 {
     double x;
     uint64_t y;
 };

 int main() {
     union double_uint64 z;
     z.x = 9007199254740992;
     printf("%lu\n", z.y);
     z.x = 9007199254740993;
     printf("%lu\n", z.y);
 }
 }}}

 In Haskell, we have

 {{{#!hs
 > (9007199254740993 :: Double) == (9007199254740992 :: Double)
 True
 }}}

 Thus, `[9007199254740992,9007199254740993..9007199254740994]::[Double]` is
 equivalent to
 `[9007199254740992,9007199254740992..9007199254740994]::[Double]`, the
 later will produce infinite list.

 For the second example, `[9007199254740993..9007199254740991]::[Double]`
 should be `[]`, but the program is equivalent to

 {{{#!hs
 takeWhile (<= 9007199254740991 + 1 / 2) [9007199254740993,
 9007199254740993 + 1, 9007199254740993 + 2, 9007199254740993 + 3, ... ]
 }}}

 We have:

 {{{#!hs
 > :m +Data.Binary
 > :m +Data.ByteString.Lazy
 > unpack $ encode ((9007199254740991 + 1 / 2) :: Double)
 [1,1,0,0,0,0,0,0,0,7,0,0,0,0,0,0,16,0,0,0,0,0,0,0,1]
 > unpack $ encode ((9007199254740993) :: Double)
 [1,1,0,0,0,0,0,0,0,7,0,0,0,0,0,0,16,0,0,0,0,0,0,0,1]
 > unpack $ encode ((9007199254740993 + 1) :: Double)
 [1,1,0,0,0,0,0,0,0,7,0,0,0,0,0,0,16,0,0,0,0,0,0,0,1]
 > unpack $ encode ((9007199254740993 + 2) :: Double)
 [1,1,0,0,0,0,0,0,0,7,1,0,0,0,0,0,16,0,0,0,0,0,0,0,1]
 }}}

 Then we get the error. A possible improvement should be replacing the
 `1/2` with a smaller number (such as `0.1`), but when the base number
 `9007199254740991` grows up, we will get into trouble again.

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


More information about the ghc-tickets mailing list