-- Stability : experimental
-- Portability : portable
--
--- This module defines bitwise operations for signed and unsigned
--- integers. Instances of the class 'Bits' for the 'Int' and
--- 'Integer' types are available from this module, and instances for
--- explicitly sized integral types are available from the
--- "Data.Int" and "Data.Word" modules.
+-- This module defines bitwise operations for signed and unsigned
+-- integers. Instances of the class 'Bits' for the 'Int' and
+-- 'Integer' types are available from this module, and instances for
+-- explicitly sized integral types are available from the
+-- "Data.Int" and "Data.Word" modules.
--
-----------------------------------------------------------------------------
{-| Reverse all the bits in the argument -}
complement :: a -> a
- {-| Shift the argument left by the specified number of bits.
- Right shifts (signed) are specified by giving a negative value.
+ {-| @'shift' x i@ shifts @x@ left by @i@ bits if @i@ is positive,
+ or right by @-i@ bits otherwise.
+ Right shifts perform sign extension on signed number types;
+ i.e. they fill the top bits with 1 if the @x@ is negative
+ and with 0 otherwise.
An instance can define either this unified 'shift' or 'shiftL' and
'shiftR', depending on which is more convenient for the type in
| i==0 = x
| i>0 = x `shiftL` i
- {-| Rotate the argument left by the specified number of bits.
- Right rotates are specified by giving a negative value.
+ {-| @'rotate' x i@ rotates @x@ left by @i@ bits if @i@ is positive,
+ or right by @-i@ bits otherwise.
For unbounded types like 'Integer', 'rotate' is equivalent to 'shift'.
shiftL :: a -> Int -> a
x `shiftL` i = x `shift` i
- {-| Shift the argument right (signed) by the specified number of bits
+ {-| Shift the first argument right by the specified number of bits
(which must be non-negative).
+ Right shifts perform sign extension on signed number types;
+ i.e. they fill the top bits with 1 if the @x@ is negative
+ and with 0 otherwise.
An instance can define either this and 'shiftL' or the unified
'shift', depending on which is more convenient for the type in
x `rotateR` i = x `rotate` (-i)
instance Bits Int where
+ {-# INLINE shift #-}
+
#ifdef __GLASGOW_HASKELL__
(I# x#) .&. (I# y#) = I# (word2Int# (int2Word# x# `and#` int2Word# y#))
(I# x#) .|. (I# y#) = I# (word2Int# (int2Word# x# `or#` int2Word# y#))
| i# >=# 0# = I# (x# `iShiftL#` i#)
| otherwise = I# (x# `iShiftRA#` negateInt# i#)
(I# x#) `rotate` (I# i#) =
- I# (word2Int# ((x'# `shiftL#` i'#) `or#`
- (x'# `shiftRL#` (wsib -# i'#))))
+ I# (word2Int# ((x'# `uncheckedShiftL#` i'#) `or#`
+ (x'# `uncheckedShiftRL#` (wsib -# i'#))))
where
x'# = int2Word# x#
i'# = word2Int# (int2Word# i# `and#` int2Word# (wsib -# 1#))