-
Notifications
You must be signed in to change notification settings - Fork 16
Open
Description
The pitfalls of toRational
and realToFrac
are well-known:
- https://hackage.haskell.org/package/base-4.21.0.0/docs/Prelude.html#v:realToFrac
- https://github.com/NorfairKing/haskell-WAT#real-double
- https://ro-che.info/articles/2019-05-14-convert-cdouble-to-double
> toRational (read "Infinity" :: Double)
179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216 % 1
> toRational (read "NaN" :: Double)
269653970229347386159395778618353710042696546841345985910145121736599013708251444699062715983611304031680170819807090036488184653221624933739271145959211186566651840137298227914453329401869141179179624428127508653257226023513694322210869665811240855745025766026879447359920868907719574457253034494436336205824 % 1
> realToFrac (read "NaN" :: Double) -- With -O0
Infinity
> realToFrac (read "NaN" :: Double) -- With -O1
NaN
> realToFrac (read "NaN" :: Double) :: CDouble
Infinity
> realToFrac (read "NaN" :: CDouble) :: Double
Infinity
This all can be fixed with
instance Real Double where
+ toRational x
+ | isInfinite x = if x > 0 then GHC.Real.infinity else -GHC.Real.infinity
+ | isNaN x = GHC.Real.notANumber
toRational (D# x#) =
case integerDecodeDouble# x# of ...
(Is GHC.Real.infinity
hacky? Definitely. But infinitely better than returning 2696539702293...
and 300 more digits)
Earlier discussion: https://mail.haskell.org/pipermail/haskell-prime/2006-February/000791.html
The MR is available at https://gitlab.haskell.org/ghc/ghc/-/merge_requests/14413
NorfairKing, matil019, tbidne, ChickenProp, Daniel-Diaz and 18 moresergv
Metadata
Metadata
Assignees
Labels
No labels