I couldn't find documentation for this behaviour and it looks like a bug. 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
.