[GHC] #15271: 1e1000000000 :: Double yields 0.0 instead of Infinity

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

[GHC] #15271: 1e1000000000 :: Double yields 0.0 instead of Infinity

GHC - devs mailing list
#15271: 1e1000000000 :: Double yields 0.0 instead of Infinity
-------------------------------------+-------------------------------------
           Reporter:  claude         |             Owner:  (none)
               Type:  bug            |            Status:  new
           Priority:  normal         |         Milestone:  8.6.1
          Component:  Compiler       |           Version:  8.4.3
           Keywords:                 |  Operating System:  Unknown/Multiple
       Architecture:                 |   Type of failure:  Incorrect result
  Unknown/Multiple                   |  at runtime
          Test Case:                 |        Blocked By:
           Blocking:                 |   Related Tickets:
Differential Rev(s):                 |         Wiki Page:
-------------------------------------+-------------------------------------
 (This bug report is about the incorrect result not the poor performance.)

 Very large positive exponent in floating point literal at Double type
 gives `0` instead of `Infinity` in `ghci-8.4.3` (self-compiled on Debian
 Buster x86_64 / amd64):

 {{{
 $ ghci
 GHCi, version 8.4.3: http://www.haskell.org/ghc/  :? for help
 Prelude> :set +s
 Prelude> 1e100000000 :: Double
 Infinity
 (5.70 secs, 68,552 bytes)
 Prelude> 1e1000000000 :: Double
 0.0
 (69.35 secs, 60,088 bytes)
 }}}

 Writing `10^` instead of `1e` completes almost instantly with the correct
 result (`Infinity`) in both cases.

 More precisely,

 {{{
 Prelude> 1e646457008 :: Double
 Infinity
 (40.80 secs, 64,272 bytes)
 Prelude> 1e646457009 :: Double
 0.0
 (40.46 secs, 60,088 bytes)
 }}}

 Note:

 {{{#!hs
 (floor $ 2^31 / logBase 2 10 + 16) == 646457009
 }}}

 This vague numerology makes me think something C `int`-related is
 overflowing somewhere (GMP? integer-gmp? GHC?).

 Standalone test program:

 {{{#!hs
 main = do
   print 1e646457008
   print 1e646457009
 }}}

 Interestingly, it doesn't occur, or at least not near the same threshold,
 in 32-bit `ghci-8.0.1` (Debian Stretch i686), though it aborts when
 getting too large (the 32-bit i686 machine has 1GB RAM and 4GB swap, the
 64-bit x86_64/amd64 has 32GB RAM).  The sheer time it takes to run makes
 bisecting the exact threshold on i686 not something I want to take on
 (though if someone writes some code that can do it programmatically I'd be
 happy to run it overnight if it would help).

 {{{
 $ ghci
 GHCi, version 8.0.1: http://www.haskell.org/ghc/  :? for help
 Prelude> :set +s
 Prelude> 1e646457008 :: Double
 Infinity
 (415.26 secs, 17,908 bytes)
 Prelude> 1e646457009 :: Double
 Infinity
 (417.66 secs, 17,820 bytes)
 Prelude> 1e746457298 :: Double
 Infinity
 (490.00 secs, 17,820 bytes)
 Prelude> 1e1000000000 :: Double
 GNU MP: Cannot allocate memory (size=419438600)
 Aborted
 $
 }}}

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

_______________________________________________
ghc-tickets mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-tickets
Reply | Threaded
Open this post in threaded view
|

Re: [GHC] #15271: 1e1000000000 :: Double yields 0.0 instead of Infinity

GHC - devs mailing list
#15271: 1e1000000000 :: Double yields 0.0 instead of Infinity
-------------------------------------+-------------------------------------
        Reporter:  claude            |                Owner:  (none)
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:  8.6.1
       Component:  Compiler          |              Version:  8.4.3
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
 Type of failure:  Incorrect result  |  Unknown/Multiple
  at runtime                         |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------
Description changed by claude:

Old description:

> (This bug report is about the incorrect result not the poor performance.)
>
> Very large positive exponent in floating point literal at Double type
> gives `0` instead of `Infinity` in `ghci-8.4.3` (self-compiled on Debian
> Buster x86_64 / amd64):
>
> {{{
> $ ghci
> GHCi, version 8.4.3: http://www.haskell.org/ghc/  :? for help
> Prelude> :set +s
> Prelude> 1e100000000 :: Double
> Infinity
> (5.70 secs, 68,552 bytes)
> Prelude> 1e1000000000 :: Double
> 0.0
> (69.35 secs, 60,088 bytes)
> }}}
>
> Writing `10^` instead of `1e` completes almost instantly with the correct
> result (`Infinity`) in both cases.
>
> More precisely,
>
> {{{
> Prelude> 1e646457008 :: Double
> Infinity
> (40.80 secs, 64,272 bytes)
> Prelude> 1e646457009 :: Double
> 0.0
> (40.46 secs, 60,088 bytes)
> }}}
>
> Note:
>
> {{{#!hs
> (floor $ 2^31 / logBase 2 10 + 16) == 646457009
> }}}
>
> This vague numerology makes me think something C `int`-related is
> overflowing somewhere (GMP? integer-gmp? GHC?).
>
> Standalone test program:
>
> {{{#!hs
> main = do
>   print 1e646457008
>   print 1e646457009
> }}}
>
> Interestingly, it doesn't occur, or at least not near the same threshold,
> in 32-bit `ghci-8.0.1` (Debian Stretch i686), though it aborts when
> getting too large (the 32-bit i686 machine has 1GB RAM and 4GB swap, the
> 64-bit x86_64/amd64 has 32GB RAM).  The sheer time it takes to run makes
> bisecting the exact threshold on i686 not something I want to take on
> (though if someone writes some code that can do it programmatically I'd
> be happy to run it overnight if it would help).
>
> {{{
> $ ghci
> GHCi, version 8.0.1: http://www.haskell.org/ghc/  :? for help
> Prelude> :set +s
> Prelude> 1e646457008 :: Double
> Infinity
> (415.26 secs, 17,908 bytes)
> Prelude> 1e646457009 :: Double
> Infinity
> (417.66 secs, 17,820 bytes)
> Prelude> 1e746457298 :: Double
> Infinity
> (490.00 secs, 17,820 bytes)
> Prelude> 1e1000000000 :: Double
> GNU MP: Cannot allocate memory (size=419438600)
> Aborted
> $
> }}}
New description:

 (This bug report is about the incorrect result not the poor performance.)

 Very large positive exponent in floating point literal at Double type
 gives `0` instead of `Infinity` in `ghci-8.4.3` (self-compiled on Debian
 Buster x86_64 / amd64):

 {{{
 $ ghci
 GHCi, version 8.4.3: http://www.haskell.org/ghc/  :? for help
 Prelude> :set +s
 Prelude> 1e100000000 :: Double
 Infinity
 (5.70 secs, 68,552 bytes)
 Prelude> 1e1000000000 :: Double
 0.0
 (69.35 secs, 60,088 bytes)
 }}}

 Writing `10^` instead of `1e` completes almost instantly with the correct
 result (`Infinity`) in both cases.

 More precisely,

 {{{
 Prelude> 1e646457008 :: Double
 Infinity
 (40.80 secs, 64,272 bytes)
 Prelude> 1e646457009 :: Double
 0.0
 (40.46 secs, 60,088 bytes)
 }}}

 Note:

 {{{#!hs
 (floor $ 2^31 / logBase 2 10 + 16) == 646457009
 }}}

 This vague numerology makes me think something C `int`-related is
 overflowing somewhere (GMP? integer-gmp? GHC?).

 Standalone test program:

 {{{#!hs
 main = do
   print 1e646457008
   print 1e646457009
 }}}

 Interestingly, it doesn't occur, or at least not near the same threshold,
 in 32-bit `ghci-8.0.1` (Debian Stretch i686), though it aborts when
 getting too large (the 32-bit i686 machine has 1GB RAM and 4GB swap, the
 64-bit x86_64/amd64 has 32GB RAM).  The sheer time it takes to run makes
 bisecting the exact threshold on i686 not something I want to take on
 (though if someone writes some code that can do it programmatically I'd be
 happy to run it overnight if it would help).

 {{{
 $ ghci
 GHCi, version 8.0.1: http://www.haskell.org/ghc/  :? for help
 Prelude> :set +s
 Prelude> 1e646457008 :: Double
 Infinity
 (415.26 secs, 17,908 bytes)
 Prelude> 1e646457009 :: Double
 Infinity
 (417.66 secs, 17,820 bytes)
 Prelude> 1e746457298 :: Double
 Infinity
 (490.00 secs, 17,820 bytes)
 Prelude> 1e1000000000 :: Double
 GNU MP: Cannot allocate memory (size=419438600)
 Aborted
 $
 }}}

 `ghci-8.0.2` on Debian Buster amd64 exhibits the problem also.

--

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

_______________________________________________
ghc-tickets mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-tickets
Reply | Threaded
Open this post in threaded view
|

Re: [GHC] #15271: 1e1000000000 :: Double yields 0.0 instead of Infinity

GHC - devs mailing list
In reply to this post by GHC - devs mailing list
#15271: 1e1000000000 :: Double yields 0.0 instead of Infinity
-------------------------------------+-------------------------------------
        Reporter:  claude            |                Owner:  (none)
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:  8.6.1
       Component:  Compiler          |              Version:  8.4.3
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
 Type of failure:  Incorrect result  |  Unknown/Multiple
  at runtime                         |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by sighingnow):

 Currently we store literal rationals as `Rational` in parsed ast, that
 means, for `1e5`, we will have:

 {{{#!hs
 (HsFractional
     (FL (SourceText "1e1000")
         (False)
         (:% (100000) (1))))
 }}}

 Note that we have evaluate `1e5` as `100000`. A possible fix for this
 problem would be:

 1. In `readRational__` (in compiler/utils/Util.hs), we only validate the
 format of literal numbers, don't evaluate it.
 2. We evaluate the literal to numeric value during code generation, after
 typechecking. Then we can know the type of the literal number and once
 when we know the value is larger than the maximum bound of `Float/Double`
 type, we can safely feed a `Infinity` value into the cell, without
 evaluating the whole literal string and knowing the true `Rational` value
 of the literal.

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

_______________________________________________
ghc-tickets mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-tickets