I couldn't find documentation for this behaviour and it looks like a bug ([Edit] it is indeed : gitlab.haskell.org/ghc/ghc/-/issues/10387). Am I missing something ?
In GHCi :
> import GHC.Real
> inf = 1/O :: Double
> inf
Infinity
> infinity
1 % 0
> fromRational infinity
Infinity
> toRational inf
179769313486231590... % 1
> toRational inf == infinity
False
[Edit : ]
There is a workaround. Using the package ieee754, one can define the following :
import GHC.Real
import qualified Numeric.IEEE as IEEE
toRational' :: (IEEE.IEEE a, Real a) => a -> Rational
toRational' a
| a == IEEE.infinity = infinity
| a == -IEEE.infinity = -infinity
| otherwise = toRational a
I think toRational
does not take into account the positive (and negative) infinity cases. It just looks to the binary format of the Double
.
Positive infinity is represented in hex as 0x7FF0000000000000
, which looks in binary as:
SEEEEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
0111111111110000000000000000000000000000000000000000000000000000
The exponent is thus the maximum value, and the mantisse is empty, which means that, if we don't take infinity into account, is equivalent to 21024ā1.79769313486231590Ć10308 (the exponent is 2047, but the exponent should be subtracted by 1023, so 1024). So it essentially performs a binary interpretation of the Double
and casts that to a Rational
.