1 {-# OPTIONS -fno-implicit-prelude #-}
2 -----------------------------------------------------------------------------
5 -- Copyright : (c) The University of Glasgow 2002
6 -- License : BSD-style (see the file libraries/core/LICENSE)
8 -- Maintainer : libraries@haskell.org
9 -- Stability : provisional
10 -- Portability : portable
12 -- $Id: Numeric.hs,v 1.7 2002/04/24 16:31:37 simonmar Exp $
14 -- Odds and ends, mostly functions for reading and showing
15 -- RealFloat-like kind of values.
17 -----------------------------------------------------------------------------
21 fromRat, -- :: (RealFloat a) => Rational -> a
22 showSigned, -- :: (Real a) => (a -> ShowS) -> Int -> a -> ShowS
23 readSigned, -- :: (Real a) => ReadS a -> ReadS a
25 readInt, -- :: (Integral a) => a -> (Char -> Bool)
26 -- -> (Char -> Int) -> ReadS a
27 readDec, -- :: (Integral a) => ReadS a
28 readOct, -- :: (Integral a) => ReadS a
29 readHex, -- :: (Integral a) => ReadS a
31 showInt, -- :: Integral a => a -> ShowS
32 showIntAtBase, -- :: Integral a => a -> (a -> Char) -> a -> ShowS
33 showHex, -- :: Integral a => a -> ShowS
34 showOct, -- :: Integral a => a -> ShowS
35 showBin, -- :: Integral a => a -> ShowS
37 showEFloat, -- :: (RealFloat a) => Maybe Int -> a -> ShowS
38 showFFloat, -- :: (RealFloat a) => Maybe Int -> a -> ShowS
39 showGFloat, -- :: (RealFloat a) => Maybe Int -> a -> ShowS
40 showFloat, -- :: (RealFloat a) => a -> ShowS
41 readFloat, -- :: (RealFloat a) => ReadS a
43 floatToDigits, -- :: (RealFloat a) => Integer -> a -> ([Int], Int)
44 lexDigits, -- :: ReadS String
50 #ifdef __GLASGOW_HASKELL__
58 import Text.ParserCombinators.ReadP( ReadP, readP_to_S, pfail )
59 import qualified Text.Read.Lex as L
67 -- *********************************************************
69 -- \subsection{Reading}
71 -- *********************************************************
73 readInt :: Num a => a -> (Char -> Bool) -> (Char -> Int) -> ReadS a
74 readInt base isDigit valDigit = readP_to_S (L.readIntP base isDigit valDigit)
76 readOct, readDec, readHex :: Num a => ReadS a
77 readOct = readP_to_S L.readOctP
78 readDec = readP_to_S L.readDecP
79 readHex = readP_to_S L.readHexP
81 readFloat :: RealFrac a => ReadS a
82 readFloat = readP_to_S readFloatP
84 readFloatP :: RealFrac a => ReadP a
86 do L.Number x <- L.lex
87 case L.numberToRational x of
89 Just y -> return (fromRational y)
91 -- It's turgid to have readSigned work using list comprehensions,
92 -- but it's specified as a ReadS to ReadS transformer
93 -- With a bit of luck no one will use it.
94 readSigned :: (Real a) => ReadS a -> ReadS a
95 readSigned readPos = readParen False read'
96 where read' r = read'' r ++
103 (n,"") <- readPos str
107 -- *********************************************************
109 -- \subsection{Showing}
111 -- *********************************************************
115 #ifdef __GLASGOW_HASKELL__
116 showInt :: Integral a => a -> ShowS
118 | n < 0 = error "Numeric.showInt: can't show negative numbers"
119 | otherwise = go n cs
122 | n < 10 = case unsafeChr (ord '0' + fromIntegral n) of
124 | otherwise = case unsafeChr (ord '0' + fromIntegral r) of
125 c@(C# _) -> go q (c:cs)
127 (q,r) = n `quotRem` 10
129 -- Controlling the format and precision of floats. The code that
130 -- implements the formatting itself is in @PrelNum@ to avoid
131 -- mutual module deps.
133 {-# SPECIALIZE showEFloat ::
134 Maybe Int -> Float -> ShowS,
135 Maybe Int -> Double -> ShowS #-}
136 {-# SPECIALIZE showFFloat ::
137 Maybe Int -> Float -> ShowS,
138 Maybe Int -> Double -> ShowS #-}
139 {-# SPECIALIZE showGFloat ::
140 Maybe Int -> Float -> ShowS,
141 Maybe Int -> Double -> ShowS #-}
143 showEFloat :: (RealFloat a) => Maybe Int -> a -> ShowS
144 showFFloat :: (RealFloat a) => Maybe Int -> a -> ShowS
145 showGFloat :: (RealFloat a) => Maybe Int -> a -> ShowS
147 showEFloat d x = showString (formatRealFloat FFExponent d x)
148 showFFloat d x = showString (formatRealFloat FFFixed d x)
149 showGFloat d x = showString (formatRealFloat FFGeneric d x)
153 -- This converts a rational to a floating. This should be used in the
154 -- Fractional instances of Float and Double.
156 fromRat :: (RealFloat a) => Rational -> a
158 if x == 0 then encodeFloat 0 0 -- Handle exceptional cases
159 else if x < 0 then - fromRat' (-x) -- first.
162 -- Conversion process:
163 -- Scale the rational number by the RealFloat base until
164 -- it lies in the range of the mantissa (as used by decodeFloat/encodeFloat).
165 -- Then round the rational to an Integer and encode it with the exponent
166 -- that we got from the scaling.
167 -- To speed up the scaling process we compute the log2 of the number to get
168 -- a first guess of the exponent.
169 fromRat' :: (RealFloat a) => Rational -> a
171 where b = floatRadix r
173 (minExp0, _) = floatRange r
174 minExp = minExp0 - p -- the real minimum exponent
175 xMin = toRational (expt b (p-1))
176 xMax = toRational (expt b p)
177 p0 = (integerLogBase b (numerator x) -
178 integerLogBase b (denominator x) - p) `max` minExp
179 f = if p0 < 0 then 1 % expt b (-p0) else expt b p0 % 1
180 (x', p') = scaleRat (toRational b) minExp xMin xMax p0 (x / f)
181 r = encodeFloat (round x') p'
183 -- Scale x until xMin <= x < xMax, or p (the exponent) <= minExp.
184 scaleRat :: Rational -> Int -> Rational -> Rational ->
185 Int -> Rational -> (Rational, Int)
186 scaleRat b minExp xMin xMax p x =
189 else if x >= xMax then
190 scaleRat b minExp xMin xMax (p+1) (x/b)
191 else if x < xMin then
192 scaleRat b minExp xMin xMax (p-1) (x*b)
196 -- Exponentiation with a cache for the most common numbers.
199 expt :: Integer -> Int -> Integer
201 if base == 2 && n >= minExpt && n <= maxExpt then
206 expts :: Array Int Integer
207 expts = array (minExpt,maxExpt) [(n,2^n) | n <- [minExpt .. maxExpt]]
209 -- Compute the (floor of the) log of i in base b.
210 -- Simplest way would be just divide i by b until it's smaller then b,
211 -- but that would be very slow! We are just slightly more clever.
212 integerLogBase :: Integer -> Integer -> Int
217 -- Try squaring the base first to cut down the number of divisions.
218 let l = 2 * integerLogBase (b*b) i
219 doDiv :: Integer -> Int -> Int
220 doDiv i l = if i < b then l else doDiv (i `div` b) (l+1)
221 in doDiv (i `div` (b^l)) l
224 -- Misc utilities to show integers and floats
226 showEFloat :: (RealFloat a) => Maybe Int -> a -> ShowS
227 showFFloat :: (RealFloat a) => Maybe Int -> a -> ShowS
228 showGFloat :: (RealFloat a) => Maybe Int -> a -> ShowS
229 showFloat :: (RealFloat a) => a -> ShowS
231 showEFloat d x = showString (formatRealFloat FFExponent d x)
232 showFFloat d x = showString (formatRealFloat FFFixed d x)
233 showGFloat d x = showString (formatRealFloat FFGeneric d x)
234 showFloat = showGFloat Nothing
236 -- These are the format types. This type is not exported.
238 data FFFormat = FFExponent | FFFixed | FFGeneric
240 formatRealFloat :: (RealFloat a) => FFFormat -> Maybe Int -> a -> String
241 formatRealFloat fmt decs x = s
245 else if isInfinite x then
246 if x < 0 then "-Infinity" else "Infinity"
247 else if x < 0 || isNegativeZero x then
248 '-' : doFmt fmt (floatToDigits (toInteger base) (-x))
250 doFmt fmt (floatToDigits (toInteger base) x)
252 let ds = map intToDigit is
255 doFmt (if e < 0 || e > 7 then FFExponent else FFFixed)
262 [d] -> d : ".0e" ++ show (e-1)
263 d:ds -> d : '.' : ds ++ 'e':show (e-1)
265 let dec' = max dec 1 in
267 [0] -> '0':'.':take dec' (repeat '0') ++ "e0"
269 let (ei, is') = roundTo base (dec'+1) is
270 d:ds = map intToDigit
271 (if ei > 0 then init is' else is')
272 in d:'.':ds ++ "e" ++ show (e-1+ei)
276 let f 0 s ds = mk0 s ++ "." ++ mk0 ds
277 f n s "" = f (n-1) (s++"0") ""
278 f n s (d:ds) = f (n-1) (s++[d]) ds
283 let dec' = max dec 0 in
285 let (ei, is') = roundTo base (dec' + e) is
286 (ls, rs) = splitAt (e+ei) (map intToDigit is')
287 in (if null ls then "0" else ls) ++
288 (if null rs then "" else '.' : rs)
290 let (ei, is') = roundTo base dec'
291 (replicate (-e) 0 ++ is)
292 d : ds = map intToDigit
293 (if ei > 0 then is' else 0:is')
296 roundTo :: Int -> Int -> [Int] -> (Int, [Int])
297 roundTo base d is = case f d is of
299 (1, is) -> (1, 1 : is)
300 where b2 = base `div` 2
301 f n [] = (0, replicate n 0)
302 f 0 (i:_) = (if i >= b2 then 1 else 0, [])
304 let (c, ds) = f (d-1) is
306 in if i' == base then (1, 0:ds) else (0, i':ds)
309 -- Based on "Printing Floating-Point Numbers Quickly and Accurately"
310 -- by R.G. Burger and R. K. Dybvig, in PLDI 96.
311 -- This version uses a much slower logarithm estimator. It should be improved.
313 -- This function returns a list of digits (Ints in [0..base-1]) and an
316 floatToDigits :: (RealFloat a) => Integer -> a -> ([Int], Int)
318 floatToDigits _ 0 = ([0], 0)
319 floatToDigits base x =
320 let (f0, e0) = decodeFloat x
321 (minExp0, _) = floatRange x
324 minExp = minExp0 - p -- the real minimum exponent
325 -- Haskell requires that f be adjusted so denormalized numbers
326 -- will have an impossibly low exponent. Adjust for this.
327 (f, e) = let n = minExp - e0
328 in if n > 0 then (f0 `div` (b^n), e0+n) else (f0, e0)
334 (f*be*b*2, 2*b, be*b, b)
338 if e > minExp && f == b^(p-1) then
339 (f*b*2, b^(-e+1)*2, b, 1)
341 (f*2, b^(-e)*2, 1, 1)
344 if b==2 && base==10 then
345 -- logBase 10 2 is slightly bigger than 3/10 so
346 -- the following will err on the low side. Ignoring
347 -- the fraction will make it err even more.
348 -- Haskell promises that p-1 <= logBase b f < p.
349 (p - 1 + e0) * 3 `div` 10
351 ceiling ((log (fromInteger (f+1)) +
352 fromIntegral e * log (fromInteger b)) /
353 log (fromInteger base))
356 if r + mUp <= expt base n * s then n else fixup (n+1)
358 if expt base (-n) * (r + mUp) <= s then n
362 gen ds rn sN mUpN mDnN =
363 let (dn, rn') = (rn * base) `divMod` sN
366 in case (rn' < mDnN', rn' + mUpN' > sN) of
367 (True, False) -> dn : ds
368 (False, True) -> dn+1 : ds
369 (True, True) -> if rn' * 2 < sN then dn : ds else dn+1 : ds
370 (False, False) -> gen (dn:ds) rn' sN mUpN' mDnN'
373 gen [] r (s * expt base k) mUp mDn
375 let bk = expt base (-k)
376 in gen [] (r * bk) s (mUp * bk) (mDn * bk)
377 in (map fromIntegral (reverse rds), k)
380 -- ---------------------------------------------------------------------------
381 -- Integer printing functions
383 showIntAtBase :: Integral a => a -> (a -> Char) -> a -> ShowS
384 showIntAtBase base toChr n r
385 | n < 0 = error ("Numeric.showIntAtBase: applied to negative number " ++ show n)
387 case quotRem n base of { (n', d) ->
389 seq c $ -- stricter than necessary
393 if n' == 0 then r' else showIntAtBase base toChr n' r'
396 showHex :: Integral a => a -> ShowS
399 showIntAtBase 16 (toChrHex) n r
402 | d < 10 = chr (ord '0' + fromIntegral d)
403 | otherwise = chr (ord 'a' + fromIntegral (d - 10))
405 showOct :: Integral a => a -> ShowS
408 showIntAtBase 8 (toChrOct) n r
409 where toChrOct d = chr (ord '0' + fromIntegral d)
411 showBin :: Integral a => a -> ShowS
414 showIntAtBase 2 (toChrOct) n r
415 where toChrOct d = chr (ord '0' + fromIntegral d)