summaryrefslogtreecommitdiff
path: root/ghc/lib/prelude/IInteger.hs
blob: ed59ee7bdfe939429505111c22796c48bca798c2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
module PreludeCore (
	Integer(..),
	int2Integer,
	_integer_0, _integer_1, _integer_m1
    ) where

import Cls
import Core
import IInt
import IRatio		( (%) )
import ITup2		-- instances
import List		( (++), foldr )
import Prel		( not, otherwise, (&&) )
import PS		( _PackedString, _unpackPS )
import Text

------------------------------------------------------
-- a magical Integer-ish function that
-- the compiler inserts references to

int2Integer :: Int -> Integer
int2Integer (I# i#) = int2Integer# i#

------------------------------------------------------
-- some *very* heavily-used constants

_integer_0, _integer_1, _integer_m1 :: Integer
_integer_0  = 0
_integer_1  = 1
_integer_m1 = (-1)

------------------------------------------------------

instance  Eq Integer  where
    (J# a1 s1 d1) == (J# a2 s2 d2)
      = (cmpInteger# a1 s1 d1 a2 s2 d2) ==# 0#

    (J# a1 s1 d1) /= (J# a2 s2 d2)
      = (cmpInteger# a1 s1 d1 a2 s2 d2) /=# 0#

instance  Ord Integer  where
    (J# a1 s1 d1) <= (J# a2 s2 d2)
      = (cmpInteger# a1 s1 d1 a2 s2 d2) <=# 0#

    (J# a1 s1 d1) <  (J# a2 s2 d2)
      = (cmpInteger# a1 s1 d1 a2 s2 d2) <# 0#

    (J# a1 s1 d1) >= (J# a2 s2 d2)
      = (cmpInteger# a1 s1 d1 a2 s2 d2) >=# 0#

    (J# a1 s1 d1) >  (J# a2 s2 d2)
      = (cmpInteger# a1 s1 d1 a2 s2 d2) ># 0#

    x@(J# a1 s1 d1) `max` y@(J# a2 s2 d2)
      = if ((cmpInteger# a1 s1 d1 a2 s2 d2) ># 0#) then x else y

    x@(J# a1 s1 d1) `min` y@(J# a2 s2 d2)
      = if ((cmpInteger# a1 s1 d1 a2 s2 d2) <# 0#) then x else y

    _tagCmp (J# a1 s1 d1) (J# a2 s2 d2)
       = case cmpInteger# a1 s1 d1 a2 s2 d2 of { res# ->
	 if res# <# 0# then _LT else 
	 if res# ># 0# then _GT else _EQ
	 }

instance  Num Integer  where
    (+) (J# a1 s1 d1) (J# a2 s2 d2)
      = plusInteger# a1 s1 d1 a2 s2 d2

    (-) (J# a1 s1 d1) (J# a2 s2 d2)
      = minusInteger# a1 s1 d1 a2 s2 d2

    negate (J# a s d) = negateInteger# a s d

    (*) (J# a1 s1 d1) (J# a2 s2 d2)
      = timesInteger# a1 s1 d1 a2 s2 d2

    -- ORIG: abs n = if n >= 0 then n else -n

    abs n@(J# a1 s1 d1)
      = case _integer_0 of { J# a2 s2 d2 ->
	if (cmpInteger# a1 s1 d1 a2 s2 d2) >=# 0#
	then n
	else negateInteger# a1 s1 d1
	}

    {- ORIG:
    signum n | n <  0 	= -1
	     | n == 0 	= 0
	     | otherwise= 1
    -}

    signum n@(J# a1 s1 d1)
      = case _integer_0	of { J# a2 s2 d2 ->
	let
	    cmp = cmpInteger# a1 s1 d1 a2 s2 d2
	in
	if      cmp >#  0# then _integer_1
	else if cmp ==# 0# then _integer_0
	else			_integer_m1
	}

    fromInteger	x	=  x

    fromInt (I# n#)	=  int2Integer# n# -- gives back a full-blown Integer

instance  Real Integer  where
    toRational x	=  x % 1

instance  Integral Integer where
    quotRem (J# a1 s1 d1) (J# a2 s2 d2)
      = case (quotRemInteger# a1 s1 d1 a2 s2 d2) of
	  _Return2GMPs a3 s3 d3 a4 s4 d4
	    -> (J# a3 s3 d3, J# a4 s4 d4)

{- USING THE UNDERLYING "GMP" CODE IS DUBIOUS FOR NOW:

    divMod (J# a1 s1 d1) (J# a2 s2 d2)
      = case (divModInteger# a1 s1 d1 a2 s2 d2) of
	  _Return2GMPs a3 s3 d3 a4 s4 d4
	    -> (J# a3 s3 d3, J# a4 s4 d4)
-}
    toInteger n	     = n
    toInt (J# a s d) = case (integer2Int# a s d) of { n# -> I# n# }

    -- the rest are identical to the report default methods;
    -- you get slightly better code if you let the compiler
    -- see them right here:
    n `quot` d	=  q  where (q,r) = quotRem n d
    n `rem` d	=  r  where (q,r) = quotRem n d
    n `div` d	=  q  where (q,r) = divMod n d
    n `mod` d	=  r  where (q,r) = divMod n d

    divMod n d 	=  case (quotRem n d) of { qr@(q,r) ->
		   if signum r == - signum d then (q-1, r+d) else qr }
		   -- Case-ified by WDP 94/10

    even x = (==) (rem x 2) 0
    odd x  = (/=) (rem x 2) 0

instance  Ix Integer  where
    range (m,n)		=  [m..n]
    index b@(m,n) i
	| inRange b i	=  fromInteger (i - m)
	| otherwise	=  error ("Ix.Integer.index{PreludeCore}: Index "
				  ++ show i ++ " outside the range "
				  ++ show b ++ ".\n")
    inRange (m,n) i	=  m <= i && i <= n

instance  Enum Integer  where
{- RAW PRELUDE ************************
    enumFrom		=  numericEnumFrom
    enumFromThen	=  numericEnumFromThen
-}
    enumFrom n = n : enumFrom (n + 1)
    enumFromThen m n = en' m (n - m)
	    where en' m n = m : en' (m + n) n


instance  Text Integer  where
    readsPrec p x = readSigned readDec x
    showsPrec   x = showSigned showInt x