From 45afba05c6d0fca1e1b2d101c097a7738bb73b25 Mon Sep 17 00:00:00 2001 From: simonpj Date: Tue, 18 Jun 2002 09:31:06 +0000 Subject: [PATCH] [project @ 2002-06-18 09:31:05 by simonpj] -------------------------- Deal with NaN and Infinity -------------------------- This commit arranges that * GHC.Real exports infinity :: Rational = 1 :% 0 notANumber :: Rational = 0 :% 0 * GHC.Float.fromRat converts these Rational non-numbers into their Float/Double equivalents As a result, arith015/arith016 start to work again. We can read NaN and Infinity into Float/Double. --- GHC/Float.lhs | 19 ++++++++++++------- GHC/Real.lhs | 7 +++++++ Text/Read/Lex.hs | 17 +---------------- 3 files changed, 20 insertions(+), 23 deletions(-) diff --git a/GHC/Float.lhs b/GHC/Float.lhs index 382ef64..5c68de4 100644 --- a/GHC/Float.lhs +++ b/GHC/Float.lhs @@ -675,14 +675,18 @@ fromRat x = x' Now, here's Lennart's code (which works) \begin{code} -{-# SPECIALISE fromRat :: - Rational -> Double, - Rational -> Float #-} +{-# SPECIALISE fromRat :: Rational -> Double, + Rational -> Float #-} fromRat :: (RealFloat a) => Rational -> a -fromRat x - | x == 0 = encodeFloat 0 0 -- Handle exceptional cases - | x < 0 = - fromRat' (-x) -- first. - | otherwise = fromRat' x + +-- Deal with special cases first, delegating the real work to fromRat' +fromRat (n :% 0) | n > 0 = 1/0 -- +Infinity + | n == 0 = 0/0 -- NaN + | n < 0 = -1/0 -- -Infinity + +fromRat (n :% d) | n > 0 = fromRat' (n :% d) + | n == 0 = encodeFloat 0 0 -- Zero + | n < 0 = - fromRat' ((-n) :% d) -- Conversion process: -- Scale the rational number by the RealFloat base until @@ -693,6 +697,7 @@ fromRat x -- a first guess of the exponent. fromRat' :: (RealFloat a) => Rational -> a +-- Invariant: argument is strictly positive fromRat' x = r where b = floatRadix r p = floatDigits r diff --git a/GHC/Real.lhs b/GHC/Real.lhs index 13be142..be30073 100644 --- a/GHC/Real.lhs +++ b/GHC/Real.lhs @@ -41,6 +41,13 @@ default () -- Double isn't available yet, \begin{code} data (Integral a) => Ratio a = !a :% !a deriving (Eq) type Rational = Ratio Integer + +infinity, notANumber :: Rational +infinity = 1 :% 0 +notANumber = 0 :% 0 + +-- Use :%, not % for Inf/NaN; the latter would +-- immediately lead to a runtime error, because it normalises. \end{code} diff --git a/Text/Read/Lex.hs b/Text/Read/Lex.hs index f2c0469..01ca6ac 100644 --- a/Text/Read/Lex.hs +++ b/Text/Read/Lex.hs @@ -36,7 +36,7 @@ import GHC.Show( Show(.. ), showChar, showString, isSpace, isAlpha, isAlphaNum, isOctDigit, isHexDigit, toUpper ) import GHC.Real( Ratio(..), Integral, Rational, (%), fromIntegral, fromRational, - toInteger, (^), (^^) ) + toInteger, (^), (^^), infinity, notANumber ) import GHC.Float( Float, Double ) import GHC.List import GHC.Show( ShowS, shows ) @@ -284,21 +284,6 @@ lexString = -- --------------------------------------------------------------------------- -- Lexing numbers -infinity, notANumber :: Rational -infinity = 1 :% 0 -notANumber = 0 :% 0 - --- Use :%, not % for Inf/NaN, the latter would --- immediately lead to a runtime error. --- --- Note that --- isInfinite (read "Infinity" :: Float) --- or --- isInfinite (fromRational (1 :% 0)) --- still don't work, because fromRational is not OK for those cases. --- --- The whole Infinity/NaN story is a bit murky to me - type Base = Int type Digits = [Int] -- 1.7.10.4