16 _properFraction, _truncate, _round, _ceiling, _floor
20 import IChar -- instances
27 import List ( reverse, dropWhile, take, drop, repeat, (++), head, tail )
28 import Prel ( (&&), (^^), (^), not, otherwise, asTypeOf, const, (.) )
29 import PS ( _PackedString, _unpackPS )
31 import TyComplex -- for pragmas
33 -----------------------------------------------------------------
34 -- some *** NON-STANDARD *** constants (to help compiling Cls.hs)
36 i0__, iminus1__, i1__, i2__ :: Num a => a
38 {-# SPECIALIZE i0__ :: Int, Integer #-}
41 iminus1__ = fromInteger (-1)
45 r0__, rhalf__, r1__ :: Fractional a => a
48 rhalf__ = fromRational 0.5
51 -- other bits of PreludeCore that aren't classes, instances, etc.
54 absReal :: (Real a) => a -> a
55 absReal x | x >= 0 = x
58 signumReal :: (Real a) => a -> a
59 signumReal x | x == 0 = 0
64 {- *RAW PRELUDE*: NOT REALLY USED:
65 numericEnumFrom :: (Real a) => a -> [a]
66 numericEnumFromThen :: (Real a) => a -> a -> [a]
67 numericEnumFrom = iterate (+1)
68 numericEnumFromThen n m = iterate (+(m-n)) n
72 realFloatToRational :: (RealFloat a) => a -> Rational
73 realFloatToRational x = (m%1)*(b%1)^^n
74 where (m,n) = decodeFloat x
79 [In response to a request by simonpj, Joe Fasel writes:]
81 A quite reasonable request! This code was added to the Prelude just
82 before the 1.2 release, when Lennart, working with an early version
83 of hbi, noticed that (read . show) was not the identity for
84 floating-point numbers. (There was a one-bit error about half the time.)
85 The original version of the conversion function was in fact simply
86 a floating-point divide, as you suggest above. The new version is,
87 I grant you, somewhat denser.
94 --{-# GENERATE_SPECS rationalToRealFloat a{Double#,Double} #-}
95 rationalToRealFloat :: (RealFloat a) => Rational -> a
97 rationalToRealFloat x = x'
100 -- If the exponent of the nearest floating-point number to x
101 -- is e, then the significand is the integer nearest xb^(-e),
102 -- where b is the floating-point radix. We start with a good
103 -- guess for e, and if it is correct, the exponent of the
104 -- floating-point number we construct will again be e. If
105 -- not, one more iteration is needed.
107 f e = if e' == e then y else f e'
108 where y = encodeFloat (round (x * (1%b)^^e)) e
109 (_,e') = decodeFloat y
112 -- We obtain a trial exponent by doing a floating-point
113 -- division of x's numerator by its denominator. The
114 -- result of this division may not itself be the ultimate
115 -- result, because of an accumulation of three rounding
118 (s,e) = decodeFloat (fromInteger (numerator x) `asTypeOf` x'
119 / fromInteger (denominator x))
121 -------------------------------------------------------------------------
122 -- These RealFrac things are here so we can
123 -- SPECIALIZE the tapookies out of them.
124 -- Also: get rid of gratuitous lazy pattern matching.
126 _properFraction :: (RealFloat a, Integral b) => a -> (b,a)
127 _truncate, _round :: (RealFrac a, Integral b) => a -> b
128 _ceiling, _floor :: (RealFrac a, Integral b) => a -> b
130 {-# SPECIALIZE _properFraction
131 :: Double -> (Int, Double)
133 {-# SPECIALIZE _truncate
136 {-# SPECIALIZE _round
140 {-# SPECIALIZE _ceiling
143 {-# SPECIALIZE _floor
148 = case (decodeFloat x) of { (m,n) ->
149 let b = floatRadix x in
151 (fromInteger m * fromInteger b ^ n, 0)
153 case (quotRem m (b^(-n))) of { (w,r) ->
154 (fromInteger w, encodeFloat r n)
158 _truncate x = case (properFraction x) of { (m, _) -> m }
161 -- this defn differs from that in the report; uses _tagCmp
163 = case (properFraction x) of { (n,r) ->
165 m = if r < r0__ then n - i1__ else n + i1__
166 sign = signum (abs r - rhalf__) --UNUSED!
168 half_down = abs r - rhalf__
170 case (_tagCmp half_down r0__) of
172 _EQ -> if even n then n else m
175 if sign == iminus1__ then n
176 else if sign == i0__ then (if even n then n else m)
177 else if sign == i1__ then m
178 else error "_round{PreludeCore}: no match in sign\n"
183 = case (properFraction x) of { (n,r) ->
184 if r > r0__ then n + i1__ else n }
187 = case (properFraction x) of { (n,r) ->
188 if r < r0__ then n - i1__ else n }
190 -------------------------------------------------------------------------
191 -- from/by Lennart, 94/09/26
193 --module Rational(prRational, fromRationalX, tinyDouble, tinyFloat, hugeDouble, hugeFloat, tiny, huge, integerLogBase) where
195 -- Convert a Rational to a string that looks like a floating point number,
196 -- but without converting to any floating type (because of the possible overflow).
197 _showRational :: Int -> Rational -> String
202 let (r', e) = normalize r
205 startExpExp = 4 :: Int
207 -- make sure 1 <= r < 10
208 normalize :: Rational -> (Rational, Int)
209 normalize r = if r < 1 then case norm startExpExp (1 / r) 0 of (r', e) -> (10 / r', -e-1) else norm startExpExp r 0
210 where norm :: Int -> Rational -> Int -> (Rational, Int)
211 -- Invariant: r*10^e == original r
216 in if r >= tn then norm ee (r/tn) (e+n) else norm (ee-1) r e
219 drop0 (c:cs) = c : reverse (dropWhile (=='0') (reverse cs))
221 prR :: Int -> Rational -> Int -> String
222 prR n r e | r < 1 = prR n (r*10) (e-1) -- final adjustment
223 prR n r e | r >= 10 = prR n (r/10) (e+1)
225 let s = show ((_round (r * 10^n))::Integer)
227 in if e > 0 && e < 8 then
228 take e s ++ "." ++ drop0 (drop e s)
229 else if e <= 0 && e > -3 then
230 "0." ++ take (-e) (repeat '0') ++ drop0 s
232 head s : "."++ drop0 (tail s) ++ "e" ++ show e0
236 -- The Prelude version of fromRational is broken; if the denominator or nominator is
237 -- out of range it fails. So we use this (very expensive!) version instead.
239 fromRationalX :: (RealFloat a) => Rational -> a
242 rationalToRealFloat r
245 h = ceiling (huge `asTypeOf` x)
246 b = toInteger (floatRadix x)
250 {--} _trace (shows e0 ('/' : shows r' ('/' : shows h "\n"))) (
251 let d = denominator r'
254 let e = integerLogBase b (d `div` h) + 1
255 in fromRat (e0-e) (n % (d `div` (b^e)))
256 else if abs n > h then
257 let e = integerLogBase b (abs n `div` h) + 1
258 in fromRat (e0+e) ((n `div` (b^e)) % d)
260 scaleFloat e0 (rationalToRealFloat r')
261 -- now that we know things are in-bounds,
262 -- we use the "old" Prelude code.
267 -- Compute the discrete log of i in base b.
268 -- Simplest way would be just divide i by b until it's smaller then b, but that would
269 -- be very slow! We are just slightly more clever.
270 integerLogBase :: Integer -> Integer -> Int
275 -- Try squaring the base first to cut down the number of divisions.
276 let l = 2 * integerLogBase (b*b) i
277 doDiv :: Integer -> Int -> Int
278 doDiv i l = if i < b then l else doDiv (i `div` b) (l+1)
279 in doDiv (i `div` (b^l)) l
284 -- Compute smallest and largest floating point values.
285 tiny :: (RealFloat a) => a
287 let (l, _) = floatRange x
288 x = encodeFloat 1 (l-1)
291 huge :: (RealFloat a) => a
293 let (_, u) = floatRange x
295 x = encodeFloat (floatRadix x ^ d - 1) (u - d)
298 tinyDouble = tiny :: Double
299 tinyFloat = tiny :: Float
300 hugeDouble = huge :: Double
301 hugeFloat = huge :: Float
303 -----------------------------------------------------------------
304 -- It is problematic having this in Cls.hs
305 -- (You really don't want to know why -- WDP 94/12)
307 _readList :: Text a => ReadS [a]
309 _readList = readParen False (\r -> [pr | ("[",s) <- lex r,
311 where readl s = [([],t) | ("]",t) <- lex s] ++
312 [(x:xs,u) | (x,t) <- reads s,
314 readl2 s = [([],t) | ("]",t) <- lex s] ++
315 [(x:xs,v) | (",",t) <- lex s,
319 _showList :: Text a => [a] -> ShowS
321 _showList [] = showString "[]"
323 = showChar '[' . shows x . showl xs
325 where showl [] = showChar ']'
326 showl (x:xs) = showString ", " . shows x . showl xs