1 {-# OPTIONS -fno-implicit-prelude #-}
2 -----------------------------------------------------------------------------
5 -- Copyright : (c) The University of Glasgow 2001
6 -- License : BSD-style (see the file libraries/core/LICENSE)
8 -- Maintainer : libraries@haskell.org
9 -- Stability : experimental
10 -- Portability : portable
12 -- $Id: Bits.hs,v 1.2 2001/07/03 11:37:49 simonmar Exp $
14 -- Bitwise operations.
16 -----------------------------------------------------------------------------
20 (.&.), (.|.), xor, -- :: a -> a -> a
21 complement, -- :: a -> a
22 shift, -- :: a -> Int -> a
23 rotate, -- :: a -> Int -> a
25 setBit, -- :: a -> Int -> a
26 clearBit, -- :: a -> Int -> a
27 complementBit, -- :: a -> Int -> a
28 testBit, -- :: a -> Int -> Bool
29 bitSize, -- :: a -> Int
30 isSigned -- :: a -> Bool
32 shiftL, shiftR, -- :: Bits a => a -> Int -> a
33 rotateL, rotateR, -- :: Bits a => a -> Int -> a
35 -- instance Bits Integer
38 -- Defines the @Bits@ class containing bit-based operations.
39 -- See library document for details on the semantics of the
40 -- individual operations.
42 #ifdef __GLASGOW_HASKELL__
49 --ADR: The fixity for .|. conflicts with that for .|. in Fran.
50 -- Removing all fixities is a fairly safe fix; fixing the "one fixity
51 -- per symbol per program" limitation in Hugs would take a lot longer.
53 infixl 8 `shift`, `rotate`
59 class Num a => Bits a where
60 (.&.), (.|.), xor :: a -> a -> a
62 shift :: a -> Int -> a
63 rotate :: a -> Int -> a
65 setBit :: a -> Int -> a
66 clearBit :: a -> Int -> a
67 complementBit :: a -> Int -> a
68 testBit :: a -> Int -> Bool
73 x `setBit` i = x .|. bit i
74 x `clearBit` i = x .&. complement (bit i)
75 x `complementBit` i = x `xor` bit i
76 x `testBit` i = (x .&. bit i) /= 0
78 shiftL, shiftR :: Bits a => a -> Int -> a
79 rotateL, rotateR :: Bits a => a -> Int -> a
80 x `shiftL` i = x `shift` i
81 x `shiftR` i = x `shift` (-i)
82 x `rotateL` i = x `rotate` i
83 x `rotateR` i = x `rotate` (-i)
85 #ifdef __GLASGOW_HASKELL__
86 instance Bits Int where
87 (I# x#) .&. (I# y#) = I# (word2Int# (int2Word# x# `and#` int2Word# y#))
88 (I# x#) .|. (I# y#) = I# (word2Int# (int2Word# x# `or#` int2Word# y#))
89 (I# x#) `xor` (I# y#) = I# (word2Int# (int2Word# x# `xor#` int2Word# y#))
90 complement (I# x#) = I# (word2Int# (int2Word# x# `xor#` int2Word# (-1#)))
91 (I# x#) `shift` (I# i#)
92 | i# >=# 0# = I# (x# `iShiftL#` i#)
93 | otherwise = I# (x# `iShiftRA#` negateInt# i#)
94 (I# x#) `rotate` (I# i#) =
95 #if WORD_SIZE_IN_BYTES == 4
96 I# (word2Int# ((x'# `shiftL#` i'#) `or#`
97 (x'# `shiftRL#` (32# -# i'#))))
100 i'# = word2Int# (int2Word# i# `and#` int2Word# 31#)
102 I# (word2Int# ((x'# `shiftL#` i'#) `or#`
103 (x'# `shiftRL#` (64# -# i'#))))
106 i'# = word2Int# (int2Word# i# `and#` int2Word# 63#)
108 bitSize _ = WORD_SIZE_IN_BYTES * 8
111 instance Bits Integer where
112 (S# x) .&. (S# y) = S# (word2Int# (int2Word# x `and#` int2Word# y))
113 x@(S# _) .&. y = toBig x .&. y
114 x .&. y@(S# _) = x .&. toBig y
115 (J# s1 d1) .&. (J# s2 d2) =
116 case andInteger# s1 d1 s2 d2 of
119 (S# x) .|. (S# y) = S# (word2Int# (int2Word# x `or#` int2Word# y))
120 x@(S# _) .|. y = toBig x .|. y
121 x .|. y@(S# _) = x .|. toBig y
122 (J# s1 d1) .|. (J# s2 d2) =
123 case orInteger# s1 d1 s2 d2 of
126 (S# x) `xor` (S# y) = S# (word2Int# (int2Word# x `xor#` int2Word# y))
127 x@(S# _) `xor` y = toBig x `xor` y
128 x `xor` y@(S# _) = x `xor` toBig y
129 (J# s1 d1) `xor` (J# s2 d2) =
130 case xorInteger# s1 d1 s2 d2 of
133 complement (S# x) = S# (word2Int# (int2Word# x `xor#` int2Word# (0# -# 1#)))
134 complement (J# s d) = case complementInteger# s d of (# s, d #) -> J# s d
136 shift x i | i >= 0 = x * 2^i
137 | otherwise = x `div` 2^(-i)
139 rotate x i = shift x i -- since an Integer never wraps around
141 bitSize _ = error "Bits.bitSize(Integer)"