[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