3fc52fcca307bdb9fbfe3f000fe3ef62557910e5
[packages/random.git] / Numeric.hs
1 {-# OPTIONS -fno-implicit-prelude #-}
2 -----------------------------------------------------------------------------
3 -- |
4 -- Module : Numeric
5 -- Copyright : (c) The University of Glasgow 2002
6 -- License : BSD-style (see the file libraries/core/LICENSE)
7 --
8 -- Maintainer : libraries@haskell.org
9 -- Stability : provisional
10 -- Portability : portable
11 --
12 -- Odds and ends, mostly functions for reading and showing
13 -- RealFloat-like kind of values.
14 --
15 -----------------------------------------------------------------------------
16
17 module Numeric (
18
19 fromRat, -- :: (RealFloat a) => Rational -> a
20 showSigned, -- :: (Real a) => (a -> ShowS) -> Int -> a -> ShowS
21 readSigned, -- :: (Real a) => ReadS a -> ReadS a
22
23 readInt, -- :: (Integral a) => a -> (Char -> Bool)
24 -- -> (Char -> Int) -> ReadS a
25 readDec, -- :: (Integral a) => ReadS a
26 readOct, -- :: (Integral a) => ReadS a
27 readHex, -- :: (Integral a) => ReadS a
28
29 showInt, -- :: Integral a => a -> ShowS
30 showIntAtBase, -- :: Integral a => a -> (a -> Char) -> a -> ShowS
31 showHex, -- :: Integral a => a -> ShowS
32 showOct, -- :: Integral a => a -> ShowS
33 showBin, -- :: Integral a => a -> ShowS
34
35 showEFloat, -- :: (RealFloat a) => Maybe Int -> a -> ShowS
36 showFFloat, -- :: (RealFloat a) => Maybe Int -> a -> ShowS
37 showGFloat, -- :: (RealFloat a) => Maybe Int -> a -> ShowS
38 showFloat, -- :: (RealFloat a) => a -> ShowS
39 readFloat, -- :: (RealFloat a) => ReadS a
40
41 floatToDigits, -- :: (RealFloat a) => Integer -> a -> ([Int], Int)
42 lexDigits, -- :: ReadS String
43
44 ) where
45
46 import Data.Char
47
48 #ifdef __GLASGOW_HASKELL__
49 import GHC.Base
50 import GHC.Read
51 import GHC.Real
52 import GHC.Float
53 import GHC.Num
54 import GHC.Show
55 import Data.Maybe
56 import Text.ParserCombinators.ReadP( ReadP, readP_to_S, pfail )
57 import qualified Text.Read.Lex as L
58 #endif
59
60 #ifdef __HUGS__
61 import Array
62 #endif
63
64
65 -- *********************************************************
66 -- * *
67 -- \subsection{Reading}
68 -- * *
69 -- *********************************************************
70
71 readInt :: Num a => a -> (Char -> Bool) -> (Char -> Int) -> ReadS a
72 readInt base isDigit valDigit = readP_to_S (L.readIntP base isDigit valDigit)
73
74 readOct, readDec, readHex :: Num a => ReadS a
75 readOct = readP_to_S L.readOctP
76 readDec = readP_to_S L.readDecP
77 readHex = readP_to_S L.readHexP
78
79 readFloat :: RealFrac a => ReadS a
80 readFloat = readP_to_S readFloatP
81
82 readFloatP :: RealFrac a => ReadP a
83 readFloatP =
84 do L.Number x <- L.lex
85 case L.numberToRational x of
86 Nothing -> pfail
87 Just y -> return (fromRational y)
88
89 -- It's turgid to have readSigned work using list comprehensions,
90 -- but it's specified as a ReadS to ReadS transformer
91 -- With a bit of luck no one will use it.
92 readSigned :: (Real a) => ReadS a -> ReadS a
93 readSigned readPos = readParen False read'
94 where read' r = read'' r ++
95 (do
96 ("-",s) <- lex r
97 (x,t) <- read'' s
98 return (-x,t))
99 read'' r = do
100 (str,s) <- lex r
101 (n,"") <- readPos str
102 return (n,s)
103
104
105 -- *********************************************************
106 -- * *
107 -- \subsection{Showing}
108 -- * *
109 -- *********************************************************
110
111
112
113 #ifdef __GLASGOW_HASKELL__
114 showInt :: Integral a => a -> ShowS
115 showInt n cs
116 | n < 0 = error "Numeric.showInt: can't show negative numbers"
117 | otherwise = go n cs
118 where
119 go n cs
120 | n < 10 = case unsafeChr (ord '0' + fromIntegral n) of
121 c@(C# _) -> c:cs
122 | otherwise = case unsafeChr (ord '0' + fromIntegral r) of
123 c@(C# _) -> go q (c:cs)
124 where
125 (q,r) = n `quotRem` 10
126
127 -- Controlling the format and precision of floats. The code that
128 -- implements the formatting itself is in @PrelNum@ to avoid
129 -- mutual module deps.
130
131 {-# SPECIALIZE showEFloat ::
132 Maybe Int -> Float -> ShowS,
133 Maybe Int -> Double -> ShowS #-}
134 {-# SPECIALIZE showFFloat ::
135 Maybe Int -> Float -> ShowS,
136 Maybe Int -> Double -> ShowS #-}
137 {-# SPECIALIZE showGFloat ::
138 Maybe Int -> Float -> ShowS,
139 Maybe Int -> Double -> ShowS #-}
140
141 showEFloat :: (RealFloat a) => Maybe Int -> a -> ShowS
142 showFFloat :: (RealFloat a) => Maybe Int -> a -> ShowS
143 showGFloat :: (RealFloat a) => Maybe Int -> a -> ShowS
144
145 showEFloat d x = showString (formatRealFloat FFExponent d x)
146 showFFloat d x = showString (formatRealFloat FFFixed d x)
147 showGFloat d x = showString (formatRealFloat FFGeneric d x)
148 #endif
149
150 #ifdef __HUGS__
151 -- This converts a rational to a floating. This should be used in the
152 -- Fractional instances of Float and Double.
153
154 fromRat :: (RealFloat a) => Rational -> a
155 fromRat x =
156 if x == 0 then encodeFloat 0 0 -- Handle exceptional cases
157 else if x < 0 then - fromRat' (-x) -- first.
158 else fromRat' x
159
160 -- Conversion process:
161 -- Scale the rational number by the RealFloat base until
162 -- it lies in the range of the mantissa (as used by decodeFloat/encodeFloat).
163 -- Then round the rational to an Integer and encode it with the exponent
164 -- that we got from the scaling.
165 -- To speed up the scaling process we compute the log2 of the number to get
166 -- a first guess of the exponent.
167 fromRat' :: (RealFloat a) => Rational -> a
168 fromRat' x = r
169 where b = floatRadix r
170 p = floatDigits r
171 (minExp0, _) = floatRange r
172 minExp = minExp0 - p -- the real minimum exponent
173 xMin = toRational (expt b (p-1))
174 xMax = toRational (expt b p)
175 p0 = (integerLogBase b (numerator x) -
176 integerLogBase b (denominator x) - p) `max` minExp
177 f = if p0 < 0 then 1 % expt b (-p0) else expt b p0 % 1
178 (x', p') = scaleRat (toRational b) minExp xMin xMax p0 (x / f)
179 r = encodeFloat (round x') p'
180
181 -- Scale x until xMin <= x < xMax, or p (the exponent) <= minExp.
182 scaleRat :: Rational -> Int -> Rational -> Rational ->
183 Int -> Rational -> (Rational, Int)
184 scaleRat b minExp xMin xMax p x =
185 if p <= minExp then
186 (x, p)
187 else if x >= xMax then
188 scaleRat b minExp xMin xMax (p+1) (x/b)
189 else if x < xMin then
190 scaleRat b minExp xMin xMax (p-1) (x*b)
191 else
192 (x, p)
193
194 -- Exponentiation with a cache for the most common numbers.
195 minExpt = 0::Int
196 maxExpt = 1100::Int
197 expt :: Integer -> Int -> Integer
198 expt base n =
199 if base == 2 && n >= minExpt && n <= maxExpt then
200 expts!n
201 else
202 base^n
203
204 expts :: Array Int Integer
205 expts = array (minExpt,maxExpt) [(n,2^n) | n <- [minExpt .. maxExpt]]
206
207 -- Compute the (floor of the) log of i in base b.
208 -- Simplest way would be just divide i by b until it's smaller then b,
209 -- but that would be very slow! We are just slightly more clever.
210 integerLogBase :: Integer -> Integer -> Int
211 integerLogBase b i =
212 if i < b then
213 0
214 else
215 -- Try squaring the base first to cut down the number of divisions.
216 let l = 2 * integerLogBase (b*b) i
217 doDiv :: Integer -> Int -> Int
218 doDiv i l = if i < b then l else doDiv (i `div` b) (l+1)
219 in doDiv (i `div` (b^l)) l
220
221
222 -- Misc utilities to show integers and floats
223
224 showEFloat :: (RealFloat a) => Maybe Int -> a -> ShowS
225 showFFloat :: (RealFloat a) => Maybe Int -> a -> ShowS
226 showGFloat :: (RealFloat a) => Maybe Int -> a -> ShowS
227 showFloat :: (RealFloat a) => a -> ShowS
228
229 showEFloat d x = showString (formatRealFloat FFExponent d x)
230 showFFloat d x = showString (formatRealFloat FFFixed d x)
231 showGFloat d x = showString (formatRealFloat FFGeneric d x)
232 showFloat = showGFloat Nothing
233
234 -- These are the format types. This type is not exported.
235
236 data FFFormat = FFExponent | FFFixed | FFGeneric
237
238 formatRealFloat :: (RealFloat a) => FFFormat -> Maybe Int -> a -> String
239 formatRealFloat fmt decs x = s
240 where base = 10
241 s = if isNaN x then
242 "NaN"
243 else if isInfinite x then
244 if x < 0 then "-Infinity" else "Infinity"
245 else if x < 0 || isNegativeZero x then
246 '-' : doFmt fmt (floatToDigits (toInteger base) (-x))
247 else
248 doFmt fmt (floatToDigits (toInteger base) x)
249 doFmt fmt (is, e) =
250 let ds = map intToDigit is
251 in case fmt of
252 FFGeneric ->
253 doFmt (if e < 0 || e > 7 then FFExponent else FFFixed)
254 (is, e)
255 FFExponent ->
256 case decs of
257 Nothing ->
258 case ds of
259 ['0'] -> "0.0e0"
260 [d] -> d : ".0e" ++ show (e-1)
261 d:ds -> d : '.' : ds ++ 'e':show (e-1)
262 Just dec ->
263 let dec' = max dec 1 in
264 case is of
265 [0] -> '0':'.':take dec' (repeat '0') ++ "e0"
266 _ ->
267 let (ei, is') = roundTo base (dec'+1) is
268 d:ds = map intToDigit
269 (if ei > 0 then init is' else is')
270 in d:'.':ds ++ "e" ++ show (e-1+ei)
271 FFFixed ->
272 case decs of
273 Nothing ->
274 let f 0 s ds = mk0 s ++ "." ++ mk0 ds
275 f n s "" = f (n-1) (s++"0") ""
276 f n s (d:ds) = f (n-1) (s++[d]) ds
277 mk0 "" = "0"
278 mk0 s = s
279 in f e "" ds
280 Just dec ->
281 let dec' = max dec 0 in
282 if e >= 0 then
283 let (ei, is') = roundTo base (dec' + e) is
284 (ls, rs) = splitAt (e+ei) (map intToDigit is')
285 in (if null ls then "0" else ls) ++
286 (if null rs then "" else '.' : rs)
287 else
288 let (ei, is') = roundTo base dec'
289 (replicate (-e) 0 ++ is)
290 d : ds = map intToDigit
291 (if ei > 0 then is' else 0:is')
292 in d : '.' : ds
293
294 roundTo :: Int -> Int -> [Int] -> (Int, [Int])
295 roundTo base d is = case f d is of
296 (0, is) -> (0, is)
297 (1, is) -> (1, 1 : is)
298 where b2 = base `div` 2
299 f n [] = (0, replicate n 0)
300 f 0 (i:_) = (if i >= b2 then 1 else 0, [])
301 f d (i:is) =
302 let (c, ds) = f (d-1) is
303 i' = c + i
304 in if i' == base then (1, 0:ds) else (0, i':ds)
305
306 --
307 -- Based on "Printing Floating-Point Numbers Quickly and Accurately"
308 -- by R.G. Burger and R. K. Dybvig, in PLDI 96.
309 -- This version uses a much slower logarithm estimator. It should be improved.
310
311 -- This function returns a list of digits (Ints in [0..base-1]) and an
312 -- exponent.
313
314 floatToDigits :: (RealFloat a) => Integer -> a -> ([Int], Int)
315
316 floatToDigits _ 0 = ([0], 0)
317 floatToDigits base x =
318 let (f0, e0) = decodeFloat x
319 (minExp0, _) = floatRange x
320 p = floatDigits x
321 b = floatRadix x
322 minExp = minExp0 - p -- the real minimum exponent
323 -- Haskell requires that f be adjusted so denormalized numbers
324 -- will have an impossibly low exponent. Adjust for this.
325 (f, e) = let n = minExp - e0
326 in if n > 0 then (f0 `div` (b^n), e0+n) else (f0, e0)
327
328 (r, s, mUp, mDn) =
329 if e >= 0 then
330 let be = b^e in
331 if f == b^(p-1) then
332 (f*be*b*2, 2*b, be*b, b)
333 else
334 (f*be*2, 2, be, be)
335 else
336 if e > minExp && f == b^(p-1) then
337 (f*b*2, b^(-e+1)*2, b, 1)
338 else
339 (f*2, b^(-e)*2, 1, 1)
340 k =
341 let k0 =
342 if b==2 && base==10 then
343 -- logBase 10 2 is slightly bigger than 3/10 so
344 -- the following will err on the low side. Ignoring
345 -- the fraction will make it err even more.
346 -- Haskell promises that p-1 <= logBase b f < p.
347 (p - 1 + e0) * 3 `div` 10
348 else
349 ceiling ((log (fromInteger (f+1)) +
350 fromIntegral e * log (fromInteger b)) /
351 log (fromInteger base))
352 fixup n =
353 if n >= 0 then
354 if r + mUp <= expt base n * s then n else fixup (n+1)
355 else
356 if expt base (-n) * (r + mUp) <= s then n
357 else fixup (n+1)
358 in fixup k0
359
360 gen ds rn sN mUpN mDnN =
361 let (dn, rn') = (rn * base) `divMod` sN
362 mUpN' = mUpN * base
363 mDnN' = mDnN * base
364 in case (rn' < mDnN', rn' + mUpN' > sN) of
365 (True, False) -> dn : ds
366 (False, True) -> dn+1 : ds
367 (True, True) -> if rn' * 2 < sN then dn : ds else dn+1 : ds
368 (False, False) -> gen (dn:ds) rn' sN mUpN' mDnN'
369 rds =
370 if k >= 0 then
371 gen [] r (s * expt base k) mUp mDn
372 else
373 let bk = expt base (-k)
374 in gen [] (r * bk) s (mUp * bk) (mDn * bk)
375 in (map fromIntegral (reverse rds), k)
376 #endif
377
378 -- ---------------------------------------------------------------------------
379 -- Integer printing functions
380
381 showIntAtBase :: Integral a => a -> (a -> Char) -> a -> ShowS
382 showIntAtBase base toChr n r
383 | n < 0 = error ("Numeric.showIntAtBase: applied to negative number " ++ show n)
384 | otherwise =
385 case quotRem n base of { (n', d) ->
386 let c = toChr d in
387 seq c $ -- stricter than necessary
388 let
389 r' = c : r
390 in
391 if n' == 0 then r' else showIntAtBase base toChr n' r'
392 }
393
394 showHex :: Integral a => a -> ShowS
395 showHex n r =
396 showString "0x" $
397 showIntAtBase 16 (toChrHex) n r
398 where
399 toChrHex d
400 | d < 10 = chr (ord '0' + fromIntegral d)
401 | otherwise = chr (ord 'a' + fromIntegral (d - 10))
402
403 showOct :: Integral a => a -> ShowS
404 showOct n r =
405 showString "0o" $
406 showIntAtBase 8 (toChrOct) n r
407 where toChrOct d = chr (ord '0' + fromIntegral d)
408
409 showBin :: Integral a => a -> ShowS
410 showBin n r =
411 showString "0b" $
412 showIntAtBase 2 (toChrOct) n r
413 where toChrOct d = chr (ord '0' + fromIntegral d)