X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=Data%2FBits.hs;h=cbf7b37015b3d1b8f732ee8a048dad9b9dd9a843;hb=HEAD;hp=8eaec9c63f900959b1552483dbda5cb0db5a71a6;hpb=258f37c7ef4af4c1ac1e9bf6dfedb53dd8a4c0e9;p=ghc-base.git diff --git a/Data/Bits.hs b/Data/Bits.hs index 8eaec9c..cbf7b37 100644 --- a/Data/Bits.hs +++ b/Data/Bits.hs @@ -1,4 +1,5 @@ -{-# OPTIONS_GHC -XNoImplicitPrelude #-} +{-# LANGUAGE CPP, NoImplicitPrelude, BangPatterns, MagicHash #-} + ----------------------------------------------------------------------------- -- | -- Module : Data.Bits @@ -48,7 +49,6 @@ module Data.Bits ( #ifdef __GLASGOW_HASKELL__ import GHC.Num -import GHC.Real import GHC.Base #endif @@ -95,9 +95,9 @@ class Num a => Bits a where question. -} shift :: a -> Int -> a - x `shift` i | i<0 = x `shiftR` (-i) - | i==0 = x - | i>0 = x `shiftL` i + x `shift` i | i<0 = x `shiftR` (-i) + | i>0 = x `shiftL` i + | otherwise = x {-| @'rotate' x i@ rotates @x@ left by @i@ bits if @i@ is positive, or right by @-i@ bits otherwise. @@ -109,9 +109,9 @@ class Num a => Bits a where question. -} rotate :: a -> Int -> a - x `rotate` i | i<0 = x `rotateR` (-i) - | i==0 = x - | i>0 = x `rotateL` i + x `rotate` i | i<0 = x `rotateR` (-i) + | i>0 = x `rotateL` i + | otherwise = x {- -- Rotation can be implemented in terms of two shifts, but care is @@ -127,7 +127,7 @@ class Num a => Bits a where | i>0 = (x `shift` i) .|. (x `shift` (i-bitSize x)) -} - -- | @bit i@ is a value with the @i@th bit set + -- | @bit i@ is a value with the @i@th bit set and all other bits clear bit :: Int -> a -- | @x \`setBit\` i@ is the same as @x .|. bit i@ @@ -152,6 +152,11 @@ class Num a => Bits a where value of the argument is ignored -} isSigned :: a -> Bool + {-# INLINE bit #-} + {-# INLINE setBit #-} + {-# INLINE clearBit #-} + {-# INLINE complementBit #-} + {-# INLINE testBit #-} bit i = 1 `shiftL` i x `setBit` i = x .|. bit i x `clearBit` i = x .&. complement (bit i) @@ -165,6 +170,7 @@ class Num a => Bits a where 'shift', depending on which is more convenient for the type in question. -} shiftL :: a -> Int -> a + {-# INLINE shiftL #-} x `shiftL` i = x `shift` i {-| Shift the first argument right by the specified number of bits @@ -177,6 +183,7 @@ class Num a => Bits a where 'shift', depending on which is more convenient for the type in question. -} shiftR :: a -> Int -> a + {-# INLINE shiftR #-} x `shiftR` i = x `shift` (-i) {-| Rotate the argument left by the specified number of bits @@ -186,6 +193,7 @@ class Num a => Bits a where 'rotate', depending on which is more convenient for the type in question. -} rotateL :: a -> Int -> a + {-# INLINE rotateL #-} x `rotateL` i = x `rotate` i {-| Rotate the argument right by the specified number of bits @@ -195,6 +203,7 @@ class Num a => Bits a where 'rotate', depending on which is more convenient for the type in question. -} rotateR :: a -> Int -> a + {-# INLINE rotateR #-} x `rotateR` i = x `rotate` (-i) instance Bits Int where @@ -218,14 +227,11 @@ instance Bits Int where I# (word2Int# ((x'# `uncheckedShiftL#` i'#) `or#` (x'# `uncheckedShiftRL#` (wsib -# i'#)))) where - x'# = int2Word# x# - i'# = word2Int# (int2Word# i# `and#` int2Word# (wsib -# 1#)) - wsib = WORD_SIZE_IN_BITS# {- work around preprocessor problem (??) -} + !x'# = int2Word# x# + !i'# = word2Int# (int2Word# i# `and#` int2Word# (wsib -# 1#)) + !wsib = WORD_SIZE_IN_BITS# {- work around preprocessor problem (??) -} bitSize _ = WORD_SIZE_IN_BITS - {-# INLINE shiftR #-} - -- same as the default definition, but we want it inlined (#2376) - x `shiftR` i = x `shift` (-i) #else /* !__GLASGOW_HASKELL__ */ #ifdef __HUGS__ @@ -274,6 +280,8 @@ instance Bits Integer where (.|.) = orInteger xor = xorInteger complement = complementInteger + shift x i@(I# i#) | i >= 0 = shiftLInteger x i# + | otherwise = shiftRInteger x (negateInt# i#) #else -- reduce bitwise binary operations to special cases we can handle @@ -290,10 +298,9 @@ instance Bits Integer where -- assuming infinite 2's-complement arithmetic complement a = -1 - a -#endif - shift x i | i >= 0 = x * 2^i | otherwise = x `div` 2^(-i) +#endif rotate x i = shift x i -- since an Integer never wraps around