2 % (c) The AQUA Project, Glasgow University, 1997-1998
5 \section[Int]{Module @Int@}
7 This code is largely copied from the Hugs library of the same name.
10 -----------------------------------------------------------------------------
12 -- Suitable for use with Hugs 1.4 on 32 bit systems.
13 -----------------------------------------------------------------------------
20 , int8ToInt -- :: Int8 -> Int
21 , intToInt8 -- :: Int -> Int8
22 , int16ToInt -- :: Int16 -> Int
23 , intToInt16 -- :: Int -> Int16
24 , int32ToInt -- :: Int32 -> Int
25 , intToInt32 -- :: Int -> Int32
26 -- plus Eq, Ord, Num, Bounded, Real, Integral, Ix, Enum, Read,
27 -- Show and Bits instances for each of Int8, Int16 and Int32
38 -----------------------------------------------------------------------------
39 -- The "official" coercion functions
40 -----------------------------------------------------------------------------
42 int8ToInt :: Int8 -> Int
43 intToInt8 :: Int -> Int8
44 int16ToInt :: Int16 -> Int
45 intToInt16 :: Int -> Int16
46 int32ToInt :: Int32 -> Int
47 intToInt32 :: Int -> Int32
49 -- And some non-exported ones
51 int8ToInt16 :: Int8 -> Int16
52 int8ToInt32 :: Int8 -> Int32
53 int16ToInt8 :: Int16 -> Int8
54 int16ToInt32 :: Int16 -> Int32
55 int32ToInt8 :: Int32 -> Int8
56 int32ToInt16 :: Int32 -> Int16
58 int8ToInt16 (I8# x) = I16# x
59 int8ToInt32 (I8# x) = I32# x
60 int16ToInt8 (I16# x) = I8# x
61 int16ToInt32 (I16# x) = I32# x
62 int32ToInt8 (I32# x) = I8# x
63 int32ToInt16 (I32# x) = I16# x
66 \subsection[Int8]{The @Int8@ interface}
70 instance CCallable Int8
71 instance CReturnable Int8
73 int8ToInt (I8# x) = I# (int8ToInt# x)
74 int8ToInt# x = if x' <=# 0x7f# then x' else x' -# 0x100#
75 where x' = word2Int# (int2Word# x `and#` int2Word# 0xff#)
78 -- This doesn't perform any bounds checking
79 -- on the value it is passed, nor its sign.
80 -- i.e., show (intToInt8 511) => "-1"
82 intToInt8 (I# x) = I8# (intToInt8# x)
83 intToInt8# i# = word2Int# ((int2Word# i#) `and#` int2Word# 0xff#)
85 instance Eq Int8 where
86 (I8# x#) == (I8# y#) = x# ==# y#
87 (I8# x#) /= (I8# y#) = x# /=# y#
89 instance Ord Int8 where
90 compare (I8# x#) (I8# y#) = compareInt# (int8ToInt# x#) (int8ToInt# y#)
92 compareInt# :: Int# -> Int# -> Ordering
98 instance Num Int8 where
99 (I8# x#) + (I8# y#) = I8# (intToInt8# (x# +# y#))
100 (I8# x#) - (I8# y#) = I8# (intToInt8# (x# -# y#))
101 (I8# x#) * (I8# y#) = I8# (intToInt8# (x# *# y#))
105 else I8# (0x100# -# x#)
109 fromInteger (J# a# s# d#)
110 = case (integer2Int# a# s# d#) of { i# -> I8# (intToInt8# i#) }
113 instance Bounded Int8 where
117 instance Real Int8 where
118 toRational x = toInteger x % 1
120 instance Integral Int8 where
121 div x@(I8# x#) y@(I8# y#) =
122 if x > 0 && y < 0 then quotInt8 (x-y-1) y
123 else if x < 0 && y > 0 then quotInt8 (x-y+1) y
125 quot x@(I8# _) y@(I8# y#) =
128 else error "Integral.Int8.quot: divide by 0\n"
129 rem x@(I8# _) y@(I8# y#) =
132 else error "Integral.Int8.rem: divide by 0\n"
133 mod x@(I8# x#) y@(I8# y#) =
134 if x > 0 && y < 0 || x < 0 && y > 0 then
135 if r/=0 then r+y else 0
138 where r = remInt8 x y
139 a@(I8# _) `quotRem` b@(I8# _) = (a `quotInt8` b, a `remInt8` b)
140 toInteger i8 = toInteger (int8ToInt i8)
141 toInt i8 = int8ToInt i8
143 remInt8 (I8# x) (I8# y) = I8# (intToInt8# ((int8ToInt# x) `remInt#` (int8ToInt# y)))
144 quotInt8 (I8# x) (I8# y) = I8# (intToInt8# ((int8ToInt# x) `quotInt#` (int8ToInt# y)))
146 instance Ix Int8 where
149 | inRange b i = int8ToInt (i - m)
150 | otherwise = error (showString "Ix{Int8}.index: Index " .
151 showParen True (showsPrec 0 i) .
152 showString " out of range " $
153 showParen True (showsPrec 0 b) "")
154 inRange (m,n) i = m <= i && i <= n
156 instance Enum Int8 where
159 enumFrom c = map toEnum [fromEnum c .. fromEnum (maxBound::Int8)]
160 enumFromThen c d = map toEnum [fromEnum c, fromEnum d .. fromEnum (last::Int8)]
161 where last = if d < c then minBound else maxBound
163 instance Read Int8 where
164 readsPrec p s = [ (intToInt8 x,r) | (x,r) <- readsPrec p s ]
166 instance Show Int8 where
167 showsPrec p i8 = showsPrec p (int8ToInt i8)
169 binop8 :: (Int32 -> Int32 -> a) -> (Int8 -> Int8 -> a)
170 binop8 op x y = int8ToInt32 x `op` int8ToInt32 y
172 instance Bits Int8 where
173 (I8# x) .&. (I8# y) = I8# (word2Int# ((int2Word# x) `and#` (int2Word# y)))
174 (I8# x) .|. (I8# y) = I8# (word2Int# ((int2Word# x) `or#` (int2Word# y)))
175 (I8# x) `xor` (I8# y) = I8# (word2Int# ((int2Word# x) `xor#` (int2Word# y)))
176 complement (I8# x) = I8# (word2Int# ((int2Word# x) `xor#` (int2Word# 0xff#)))
177 shift (I8# x) i@(I# i#)
178 | i > 0 = I8# (intToInt8# (iShiftL# (int8ToInt# x) i#))
179 | otherwise = I8# (intToInt8# (iShiftRA# (int8ToInt# x) i#))
180 i8@(I8# x) `rotate` (I# i)
183 I8# (intToInt8# ( word2Int# (
184 (int2Word# (iShiftL# (int8ToInt# x) i'))
186 (int2Word# (iShiftRA# (word2Int# (
188 (int2Word# (0x100# -# pow2# i2))))
190 | otherwise = rotate i8 (I# (8# +# i))
192 i' = word2Int# (int2Word# i `and#` int2Word# 7#)
195 setBit x i = x .|. bit i
196 clearBit x i = x .&. complement (bit i)
197 complementBit x i = x `xor` bit i
198 testBit x i = (x .&. bit i) /= 0
202 pow2# :: Int# -> Int#
203 pow2# x# = iShiftL# 1# x#
206 \subsection[Int16]{The @Int16@ interface}
209 data Int16 = I16# Int#
210 instance CCallable Int16
211 instance CReturnable Int16
213 int16ToInt (I16# x) = I# (int16ToInt# x)
215 int16ToInt# x = if x' <=# 0x7fff# then x' else x' -# 0x10000#
216 where x' = word2Int# (int2Word# x `and#` int2Word# 0xffff#)
218 intToInt16 (I# x) = I16# (intToInt16# x)
219 intToInt16# i# = word2Int# ((int2Word# i#) `and#` int2Word# 0xffff#)
221 instance Eq Int16 where
222 (I16# x#) == (I16# y#) = x# ==# y#
223 (I16# x#) /= (I16# y#) = x# /=# y#
225 instance Ord Int16 where
226 compare (I16# x#) (I16# y#) = compareInt# (int16ToInt# x#) (int16ToInt# y#)
228 instance Num Int16 where
229 (I16# x#) + (I16# y#) = I16# (intToInt16# (x# +# y#))
230 (I16# x#) - (I16# y#) = I16# (intToInt16# (x# -# y#))
231 (I16# x#) * (I16# y#) = I16# (intToInt16# (x# *# y#))
235 else I16# (0x10000# -# x#)
238 fromInteger (J# a# s# d#)
239 = case (integer2Int# a# s# d#) of { i# -> I16# (intToInt16# i#) }
242 instance Bounded Int16 where
246 instance Real Int16 where
247 toRational x = toInteger x % 1
249 instance Integral Int16 where
250 div x@(I16# x#) y@(I16# y#) =
251 if x > 0 && y < 0 then quotInt16 (x-y-1) y
252 else if x < 0 && y > 0 then quotInt16 (x-y+1) y
254 quot x@(I16# _) y@(I16# y#) =
257 else error "Integral.Int16.quot: divide by 0\n"
258 rem x@(I16# _) y@(I16# y#) =
261 else error "Integral.Int16.rem: divide by 0\n"
262 mod x@(I16# x#) y@(I16# y#) =
263 if x > 0 && y < 0 || x < 0 && y > 0 then
264 if r/=0 then r+y else 0
267 where r = remInt16 x y
268 a@(I16# _) `quotRem` b@(I16# _) = (a `quotInt16` b, a `remInt16` b)
269 toInteger i16 = toInteger (int16ToInt i16)
270 toInt i16 = int16ToInt i16
272 remInt16 (I16# x) (I16# y) = I16# (intToInt16# ((int16ToInt# x) `remInt#` (int16ToInt# y)))
273 quotInt16 (I16# x) (I16# y) = I16# (intToInt16# ((int16ToInt# x) `quotInt#` (int16ToInt# y)))
275 instance Ix Int16 where
278 | inRange b i = int16ToInt (i - m)
279 | otherwise = error (showString "Ix{Int16}.index: Index " .
280 showParen True (showsPrec 0 i) .
281 showString " out of range " $
282 showParen True (showsPrec 0 b) "")
283 inRange (m,n) i = m <= i && i <= n
285 instance Enum Int16 where
287 fromEnum = int16ToInt
288 enumFrom c = map toEnum [fromEnum c .. fromEnum (maxBound::Int16)]
289 enumFromThen c d = map toEnum [fromEnum c, fromEnum d .. fromEnum (last::Int16)]
290 where last = if d < c then minBound else maxBound
292 instance Read Int16 where
293 readsPrec p s = [ (intToInt16 x,r) | (x,r) <- readsPrec p s ]
295 instance Show Int16 where
296 showsPrec p i16 = showsPrec p (int16ToInt i16)
298 binop16 :: (Int32 -> Int32 -> a) -> (Int16 -> Int16 -> a)
299 binop16 op x y = int16ToInt32 x `op` int16ToInt32 y
301 instance Bits Int16 where
302 (I16# x) .&. (I16# y) = I16# (word2Int# ((int2Word# x) `and#` (int2Word# y)))
303 (I16# x) .|. (I16# y) = I16# (word2Int# ((int2Word# x) `or#` (int2Word# y)))
304 (I16# x) `xor` (I16# y) = I16# (word2Int# ((int2Word# x) `xor#` (int2Word# y)))
305 complement (I16# x) = I16# (word2Int# ((int2Word# x) `xor#` (int2Word# 0xffff#)))
306 shift (I16# x) i@(I# i#)
307 | i > 0 = I16# (intToInt16# (iShiftL# (int16ToInt# x) i#))
308 | otherwise = I16# (intToInt16# (iShiftRA# (int16ToInt# x) i#))
309 i16@(I16# x) `rotate` (I# i)
312 I16# (intToInt16# (word2Int# (
313 (int2Word# (iShiftL# (int16ToInt# x) i'))
315 (int2Word# (iShiftRA# ( word2Int# (
316 (int2Word# x) `and#` (int2Word# (0x100# -# pow2# i2))))
318 | otherwise = rotate i16 (I# (16# +# i))
320 i' = word2Int# (int2Word# i `and#` int2Word# 15#)
323 setBit x i = x .|. bit i
324 clearBit x i = x .&. complement (bit i)
325 complementBit x i = x `xor` bit i
326 testBit x i = (x .&. bit i) /= 0
331 \subsection[Int32]{The @Int32@ interface}
334 data Int32 = I32# Int#
335 instance CCallable Int32
336 instance CReturnable Int32
338 int32ToInt (I32# x) = I# (int32ToInt# x)
340 int32ToInt# :: Int# -> Int#
341 #if WORD_SIZE_IN_BYTES > 4
342 int32ToInt# x = if x' <=# 0x7fffffff# then x' else x' -# 0x100000000#
343 where x' = word2Int# (int2Word# x `and#` int2Word# 0xffffffff#)
348 intToInt32 (I# x) = I32# (intToInt32# x)
349 intToInt32# :: Int# -> Int#
350 #if WORD_SIZE_IN_BYTES > 4
351 intToInt32# i# = word2Int# ((int2Word# i#) `and#` int2Word# 0xffffffff#)
356 instance Eq Int32 where
357 (I32# x#) == (I32# y#) = x# ==# y#
358 (I32# x#) /= (I32# y#) = x# /=# y#
360 instance Ord Int32 where
361 compare (I32# x#) (I32# y#) = compareInt# (int32ToInt# x#) (int32ToInt# y#)
363 instance Num Int32 where
364 (I32# x#) + (I32# y#) = I32# (intToInt32# (x# +# y#))
365 (I32# x#) - (I32# y#) = I32# (intToInt32# (x# -# y#))
366 (I32# x#) * (I32# y#) = I32# (intToInt32# (x# *# y#))
367 #if WORD_SIZE_IN_BYTES > 4
371 else I32# (intToInt32# (0x100000000# -# x'))
373 negate (I32# x) = I32# (negateInt# x)
377 fromInteger (J# a# s# d#)
378 = case (integer2Int# a# s# d#) of { i# -> I32# (intToInt32# i#) }
381 -- ToDo: remove LitLit when minBound::Int is fixed (currently it's one
382 -- too high, and doesn't allow the correct minBound to be defined here).
383 instance Bounded Int32 where
384 minBound = case ``0x80000000'' of { I# x -> I32# x }
385 maxBound = I32# 0x7fffffff#
387 instance Real Int32 where
388 toRational x = toInteger x % 1
390 instance Integral Int32 where
391 div x@(I32# x#) y@(I32# y#) =
392 if x > 0 && y < 0 then quotInt32 (x-y-1) y
393 else if x < 0 && y > 0 then quotInt32 (x-y+1) y
395 quot x@(I32# _) y@(I32# y#) =
398 else error "Integral.Int32.quot: divide by 0\n"
399 rem x@(I32# _) y@(I32# y#) =
402 else error "Integral.Int32.rem: divide by 0\n"
403 mod x@(I32# x#) y@(I32# y#) =
404 if x > 0 && y < 0 || x < 0 && y > 0 then
405 if r/=0 then r+y else 0
408 where r = remInt32 x y
409 a@(I32# _) `quotRem` b@(I32# _) = (a `quotInt32` b, a `remInt32` b)
410 toInteger i32 = toInteger (int32ToInt i32)
411 toInt i32 = int32ToInt i32
413 remInt32 (I32# x) (I32# y) = I32# (intToInt32# ((int32ToInt# x) `remInt#` (int32ToInt# y)))
414 quotInt32 (I32# x) (I32# y) = I32# (intToInt32# ((int32ToInt# x) `quotInt#` (int32ToInt# y)))
416 instance Ix Int32 where
419 | inRange b i = int32ToInt (i - m)
420 | otherwise = error (showString "Ix{Int32}.index: Index " .
421 showParen True (showsPrec 0 i) .
422 showString " out of range " $
423 showParen True (showsPrec 0 b) "")
424 inRange (m,n) i = m <= i && i <= n
426 instance Enum Int32 where
428 fromEnum = int32ToInt
429 enumFrom c = map toEnum [fromEnum c .. fromEnum (maxBound::Int32)]
430 enumFromThen c d = map toEnum [fromEnum c, fromEnum d .. fromEnum (last::Int32)]
431 where last = if d < c then minBound else maxBound
433 instance Read Int32 where
434 readsPrec p s = [ (intToInt32 x,r) | (x,r) <- readsPrec p s ]
436 instance Show Int32 where
437 showsPrec p i32 = showsPrec p (int32ToInt i32)
439 instance Bits Int32 where
440 (I32# x) .&. (I32# y) = I32# (word2Int# ((int2Word# x) `and#` (int2Word# y)))
441 (I32# x) .|. (I32# y) = I32# (word2Int# ((int2Word# x) `or#` (int2Word# y)))
442 (I32# x) `xor` (I32# y) = I32# (word2Int# ((int2Word# x) `xor#` (int2Word# y)))
443 #if WORD_SIZE_IN_BYTES > 4
444 complement (I32# x) = I32# (word2Int# ((int2Word# x) `xor#` (int2Word# 0xffffffff#)))
446 complement (I32# x) = I32# (word2Int# ((int2Word# x) `xor#` (int2Word# (negateInt# 1#))))
448 shift (I32# x) i@(I# i#)
449 | i > 0 = I32# (intToInt32# (iShiftL# (int32ToInt# x) i#))
450 | otherwise = I32# (intToInt32# (iShiftRA# (int32ToInt# x) i#))
451 i32@(I32# x) `rotate` (I# i)
454 -- ( (x<<i') | ((x&(0x100000000-2^i2))>>i2)
455 I32# (intToInt32# ( word2Int# (
456 (int2Word# (iShiftL# (int32ToInt# x) i'))
458 (int2Word# (iShiftRA# (word2Int# (
461 (int2Word# (maxBound# -# pow2# i2 +# 1#))))
463 | otherwise = rotate i32 (I# (32# +# i))
465 i' = word2Int# (int2Word# i `and#` int2Word# 31#)
467 (I32# maxBound#) = maxBound
469 setBit x i = x .|. bit i
470 clearBit x i = x .&. complement (bit i)
471 complementBit x i = x `xor` bit i
472 testBit x i = (x .&. bit i) /= 0
476 {-# INLINE wordop #-}
477 wordop op (I# x) (I# y) = I# (word2Int# (int2Word# x `op` int2Word# y))
479 -----------------------------------------------------------------------------
480 -- End of exported definitions
482 -- The remainder of this file consists of definitions which are only
483 -- used in the implementation.
484 -----------------------------------------------------------------------------
486 -----------------------------------------------------------------------------
487 -- Code copied from the Prelude
488 -----------------------------------------------------------------------------
490 absReal x | x >= 0 = x
493 signumReal x | x == 0 = 0