2 % (c) The AQUA Project, Glasgow University, 1994-1996
5 \section[PrelNum]{Module @PrelNum@}
8 {-# OPTIONS -fno-implicit-prelude #-}
14 import {-# SOURCE #-} PrelErr
17 infixl 7 %, /, `quot`, `rem`, `div`, `mod`
20 %*********************************************************
22 \subsection{Standard numeric classes}
24 %*********************************************************
27 class (Num a, Ord a) => Real a where
28 toRational :: a -> Rational
30 class (Real a, Enum a) => Integral a where
31 quot, rem, div, mod :: a -> a -> a
32 quotRem, divMod :: a -> a -> (a,a)
33 toInteger :: a -> Integer
34 toInt :: a -> Int -- partain: Glasgow extension
36 n `quot` d = q where (q,r) = quotRem n d
37 n `rem` d = r where (q,r) = quotRem n d
38 n `div` d = q where (q,r) = divMod n d
39 n `mod` d = r where (q,r) = divMod n d
40 divMod n d = if signum r == negate (signum d) then (q-1, r+d) else qr
41 where qr@(q,r) = quotRem n d
43 class (Num a) => Fractional a where
46 fromRational :: Rational -> a
50 class (Fractional a) => Floating a where
52 exp, log, sqrt :: a -> a
53 (**), logBase :: a -> a -> a
54 sin, cos, tan :: a -> a
55 asin, acos, atan :: a -> a
56 sinh, cosh, tanh :: a -> a
57 asinh, acosh, atanh :: a -> a
59 x ** y = exp (log x * y)
60 logBase x y = log y / log x
63 tanh x = sinh x / cosh x
65 class (Real a, Fractional a) => RealFrac a where
66 properFraction :: (Integral b) => a -> (b,a)
67 truncate, round :: (Integral b) => a -> b
68 ceiling, floor :: (Integral b) => a -> b
70 truncate x = m where (m,_) = properFraction x
72 round x = let (n,r) = properFraction x
73 m = if r < 0 then n - 1 else n + 1
74 in case signum (abs r - 0.5) of
76 0 -> if even n then n else m
79 ceiling x = if r > 0 then n + 1 else n
80 where (n,r) = properFraction x
82 floor x = if r < 0 then n - 1 else n
83 where (n,r) = properFraction x
85 class (RealFrac a, Floating a) => RealFloat a where
86 floatRadix :: a -> Integer
87 floatDigits :: a -> Int
88 floatRange :: a -> (Int,Int)
89 decodeFloat :: a -> (Integer,Int)
90 encodeFloat :: Integer -> Int -> a
93 scaleFloat :: Int -> a -> a
94 isNaN, isInfinite, isDenormalized, isNegativeZero, isIEEE
97 exponent x = if m == 0 then 0 else n + floatDigits x
98 where (m,n) = decodeFloat x
100 significand x = encodeFloat m (negate (floatDigits x))
101 where (m,_) = decodeFloat x
103 scaleFloat k x = encodeFloat m (n+k)
104 where (m,n) = decodeFloat x
107 %*********************************************************
109 \subsection{Instances for @Int@}
111 %*********************************************************
114 instance Real Int where
115 toRational x = toInteger x % 1
117 instance Integral Int where
118 a@(I# _) `quotRem` b@(I# _) = (a `quotInt` b, a `remInt` b)
119 -- OK, so I made it a little stricter. Shoot me. (WDP 94/10)
121 -- Following chks for zero divisor are non-standard (WDP)
122 a `quot` b = if b /= 0
124 else error "Integral.Int.quot{PreludeCore}: divide by 0\n"
125 a `rem` b = if b /= 0
127 else error "Integral.Int.rem{PreludeCore}: divide by 0\n"
129 x `div` y = if x > 0 && y < 0 then quotInt (x-y-1) y
130 else if x < 0 && y > 0 then quotInt (x-y+1) y
132 x `mod` y = if x > 0 && y < 0 || x < 0 && y > 0 then
133 if r/=0 then r+y else 0
138 divMod x@(I# _) y@(I# _) = (x `div` y, x `mod` y)
139 -- Stricter. Sorry if you don't like it. (WDP 94/10)
141 --OLD: even x = eqInt (x `mod` 2) 0
142 --OLD: odd x = neInt (x `mod` 2) 0
144 toInteger (I# i) = int2Integer i -- give back a full-blown Integer
149 %*********************************************************
151 \subsection{Instances for @Integer@}
153 %*********************************************************
156 instance Ord Integer where
157 (J# a1 s1 d1) <= (J# a2 s2 d2)
158 = (cmpInteger# a1 s1 d1 a2 s2 d2) <=# 0#
160 (J# a1 s1 d1) < (J# a2 s2 d2)
161 = (cmpInteger# a1 s1 d1 a2 s2 d2) <# 0#
163 (J# a1 s1 d1) >= (J# a2 s2 d2)
164 = (cmpInteger# a1 s1 d1 a2 s2 d2) >=# 0#
166 (J# a1 s1 d1) > (J# a2 s2 d2)
167 = (cmpInteger# a1 s1 d1 a2 s2 d2) ># 0#
169 x@(J# a1 s1 d1) `max` y@(J# a2 s2 d2)
170 = if ((cmpInteger# a1 s1 d1 a2 s2 d2) ># 0#) then x else y
172 x@(J# a1 s1 d1) `min` y@(J# a2 s2 d2)
173 = if ((cmpInteger# a1 s1 d1 a2 s2 d2) <# 0#) then x else y
175 compare (J# a1 s1 d1) (J# a2 s2 d2)
176 = case cmpInteger# a1 s1 d1 a2 s2 d2 of { res# ->
177 if res# <# 0# then LT else
178 if res# ># 0# then GT else EQ
181 instance Num Integer where
182 (+) (J# a1 s1 d1) (J# a2 s2 d2)
183 = case plusInteger# a1 s1 d1 a2 s2 d2 of (# a, s, d #) -> J# a s d
185 (-) (J# a1 s1 d1) (J# a2 s2 d2)
186 = case minusInteger# a1 s1 d1 a2 s2 d2 of (# a, s, d #) -> J# a s d
189 = case negateInteger# a s d of (# a, s, d #) -> J# a s d
191 (*) (J# a1 s1 d1) (J# a2 s2 d2)
192 = case timesInteger# a1 s1 d1 a2 s2 d2 of (# a, s, d #) -> J# a s d
194 -- ORIG: abs n = if n >= 0 then n else -n
197 = case 0 of { J# a2 s2 d2 ->
198 if (cmpInteger# a1 s1 d1 a2 s2 d2) >=# 0#
200 else case negateInteger# a1 s1 d1 of (# a, s, d #) -> J# a s d
203 signum n@(J# a1 s1 d1)
204 = case 0 of { J# a2 s2 d2 ->
206 cmp = cmpInteger# a1 s1 d1 a2 s2 d2
209 else if cmp ==# 0# then 0
215 fromInt (I# i) = int2Integer i
217 instance Real Integer where
220 instance Integral Integer where
221 quotRem (J# a1 s1 d1) (J# a2 s2 d2)
222 = case (quotRemInteger# a1 s1 d1 a2 s2 d2) of
223 (# a3, s3, d3, a4, s4, d4 #)
224 -> (J# a3 s3 d3, J# a4 s4 d4)
226 {- USING THE UNDERLYING "GMP" CODE IS DUBIOUS FOR NOW:
228 divMod (J# a1 s1 d1) (J# a2 s2 d2)
229 = case (divModInteger# a1 s1 d1 a2 s2 d2) of
230 Return2GMPs a3 s3 d3 a4 s4 d4
231 -> (J# a3 s3 d3, J# a4 s4 d4)
234 toInt (J# a s d) = case (integer2Int# a s d) of { n# -> I# n# }
236 -- the rest are identical to the report default methods;
237 -- you get slightly better code if you let the compiler
238 -- see them right here:
239 n `quot` d = if d /= 0 then q else
240 error "Integral.Integer.quot{PreludeCore}: divide by 0\n"
241 where (q,r) = quotRem n d
242 n `rem` d = if d /= 0 then r else
243 error "Integral.Integer.quot{PreludeCore}: divide by 0\n"
244 where (q,r) = quotRem n d
245 n `div` d = q where (q,r) = divMod n d
246 n `mod` d = r where (q,r) = divMod n d
248 divMod n d = case (quotRem n d) of { qr@(q,r) ->
249 if signum r == negate (signum d) then (q - 1, r+d) else qr }
250 -- Case-ified by WDP 94/10
252 instance Enum Integer where
253 toEnum n = toInteger n
255 enumFrom n = n : enumFrom (n + 1)
256 enumFromThen m n = en' m (n - m)
257 where en' m n = m : en' (m + n) n
258 enumFromTo n m = takeWhile (<= m) (enumFrom n)
259 enumFromThenTo n m p = takeWhile (if m >= n then (<= p) else (>= p))
262 instance Show Integer where
263 showsPrec x = showSignedInteger x
264 showList = showList__ (showsPrec 0)
266 instance Ix Integer where
269 | inRange b i = fromInteger (i - m)
270 | otherwise = error "Integer.index: Index out of range."
271 inRange (m,n) i = m <= i && i <= n
273 showSignedInteger :: Int -> Integer -> ShowS
274 showSignedInteger p n r
275 = -- from HBC version; support code follows
276 if n < 0 && p > 6 then '(':jtos n++(')':r) else jtos n ++ r
278 jtos :: Integer -> String
285 jtos' :: Integer -> String -> String
288 chr (fromInteger (n + ord_0)) : cs
290 jtos' q (chr (toInt r + (ord_0::Int)) : cs)
292 (q,r) = n `quotRem` 10
296 %*********************************************************
298 \subsection{The @Ratio@ and @Rational@ types}
300 %*********************************************************
303 data (Integral a) => Ratio a = !a :% !a deriving (Eq)
304 type Rational = Ratio Integer
306 {-# SPECIALISE (%) :: Integer -> Integer -> Rational #-}
307 (%) :: (Integral a) => a -> a -> Ratio a
308 numerator, denominator :: (Integral a) => Ratio a -> a
311 \tr{reduce} is a subsidiary function used only in this module .
312 It normalises a ratio by dividing both numerator and denominator by
313 their greatest common divisor.
316 reduce x 0 = error "{Ratio.%}: zero denominator"
317 reduce x y = (x `quot` d) :% (y `quot` d)
322 x % y = reduce (x * signum y) (abs y)
326 denominator (x:%y) = y
329 %*********************************************************
331 \subsection{Overloaded numeric functions}
333 %*********************************************************
336 even, odd :: (Integral a) => a -> Bool
337 even n = n `rem` 2 == 0
340 {-# SPECIALISE gcd ::
342 Integer -> Integer -> Integer #-}
343 gcd :: (Integral a) => a -> a -> a
344 gcd 0 0 = error "Prelude.gcd: gcd 0 0 is undefined"
345 gcd x y = gcd' (abs x) (abs y)
347 gcd' x y = gcd' y (x `rem` y)
349 {-# SPECIALISE lcm ::
351 Integer -> Integer -> Integer #-}
352 lcm :: (Integral a) => a -> a -> a
355 lcm x y = abs ((x `quot` (gcd x y)) * y)
357 {-# SPECIALISE (^) ::
358 Integer -> Integer -> Integer,
359 Integer -> Int -> Integer,
360 Int -> Int -> Int #-}
361 (^) :: (Num a, Integral b) => a -> b -> a
363 x ^ n | n > 0 = f x (n-1) x
365 f x n y = g x n where
366 g x n | even n = g (x*x) (n `quot` 2)
367 | otherwise = f x (n-1) (x*y)
368 _ ^ _ = error "Prelude.^: negative exponent"
370 {- SPECIALISE (^^) ::
371 Double -> Int -> Double,
372 Rational -> Int -> Rational #-}
373 (^^) :: (Fractional a, Integral b) => a -> b -> a
374 x ^^ n = if n >= 0 then x^n else recip (x^(negate n))
376 atan2 :: (RealFloat a) => a -> a -> a
377 atan2 y x = case (signum y, signum x) of
381 (-1, 0) -> (negate pi)/2
382 ( _, 1) -> atan (y/x)
383 ( _,-1) -> atan (y/x) + pi
384 ( 0, 0) -> error "Prelude.atan2: atan2 of origin"