packages feed

hw-bits 0.7.1.1 → 0.7.1.2

raw patch · 8 files changed

+461/−128 lines, 8 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- HaskellWorks.Data.Bits.Broadword: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (HaskellWorks.Data.Bits.Broadword.Broadword a)
- HaskellWorks.Data.Bits.Broadword: instance GHC.Classes.Eq a => GHC.Classes.Eq (HaskellWorks.Data.Bits.Broadword.Broadword a)
- HaskellWorks.Data.Bits.Broadword: instance GHC.Generics.Generic (HaskellWorks.Data.Bits.Broadword.Broadword a)
- HaskellWorks.Data.Bits.Broadword: instance GHC.Show.Show a => GHC.Show.Show (HaskellWorks.Data.Bits.Broadword.Broadword a)
+ HaskellWorks.Data.Bits.Broadword.Type: Broadword :: a -> Broadword a
+ HaskellWorks.Data.Bits.Broadword.Type: broadword :: Broadword Word64 -> Word64
+ HaskellWorks.Data.Bits.Broadword.Type: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (HaskellWorks.Data.Bits.Broadword.Type.Broadword a)
+ HaskellWorks.Data.Bits.Broadword.Type: instance GHC.Base.Functor HaskellWorks.Data.Bits.Broadword.Type.Broadword
+ HaskellWorks.Data.Bits.Broadword.Type: instance GHC.Classes.Eq a => GHC.Classes.Eq (HaskellWorks.Data.Bits.Broadword.Type.Broadword a)
+ HaskellWorks.Data.Bits.Broadword.Type: instance GHC.Generics.Generic (HaskellWorks.Data.Bits.Broadword.Type.Broadword a)
+ HaskellWorks.Data.Bits.Broadword.Type: instance GHC.Show.Show a => GHC.Show.Show (HaskellWorks.Data.Bits.Broadword.Type.Broadword a)
+ HaskellWorks.Data.Bits.Broadword.Type: newtype Broadword a
+ HaskellWorks.Data.Bits.Broadword.Word16: h :: Int -> Word16
+ HaskellWorks.Data.Bits.Broadword.Word16: kBitDiff :: Int -> Word16 -> Word16 -> Word16
+ HaskellWorks.Data.Bits.Broadword.Word16: kBitDiffPos :: Int -> Word16 -> Word16 -> Word16
+ HaskellWorks.Data.Bits.Broadword.Word16: kBitDiffUnsafe :: Int -> Word16 -> Word16 -> Word16
+ HaskellWorks.Data.Bits.Broadword.Word16: l :: Int -> Word16
+ HaskellWorks.Data.Bits.Broadword.Word32: h :: Int -> Word32
+ HaskellWorks.Data.Bits.Broadword.Word32: kBitDiff :: Int -> Word32 -> Word32 -> Word32
+ HaskellWorks.Data.Bits.Broadword.Word32: kBitDiffPos :: Int -> Word32 -> Word32 -> Word32
+ HaskellWorks.Data.Bits.Broadword.Word32: kBitDiffUnsafe :: Int -> Word32 -> Word32 -> Word32
+ HaskellWorks.Data.Bits.Broadword.Word32: l :: Int -> Word32
+ HaskellWorks.Data.Bits.Broadword.Word64: h :: Int -> Word64
+ HaskellWorks.Data.Bits.Broadword.Word64: kBitDiff :: Int -> Word64 -> Word64 -> Word64
+ HaskellWorks.Data.Bits.Broadword.Word64: kBitDiffPos :: Int -> Word64 -> Word64 -> Word64
+ HaskellWorks.Data.Bits.Broadword.Word64: kBitDiffUnsafe :: Int -> Word64 -> Word64 -> Word64
+ HaskellWorks.Data.Bits.Broadword.Word64: l :: Int -> Word64
+ HaskellWorks.Data.Bits.Broadword.Word8: h :: Int -> Word8
+ HaskellWorks.Data.Bits.Broadword.Word8: kBitDiff :: Int -> Word8 -> Word8 -> Word8
+ HaskellWorks.Data.Bits.Broadword.Word8: kBitDiffPos :: Int -> Word8 -> Word8 -> Word8
+ HaskellWorks.Data.Bits.Broadword.Word8: kBitDiffUnsafe :: Int -> Word8 -> Word8 -> Word8
+ HaskellWorks.Data.Bits.Broadword.Word8: l :: Int -> Word8
+ HaskellWorks.Data.Bits.Word64: lsb :: Word64 -> Word64

Files

hw-bits.cabal view
@@ -1,7 +1,7 @@ cabal-version:  2.2  name:                   hw-bits-version:                0.7.1.1+version:                0.7.1.2 synopsis:               Bit manipulation description:            Please see README.md category:               Data, Bit@@ -71,6 +71,11 @@                         HaskellWorks.Data.Bits.BitShown                         HaskellWorks.Data.Bits.BitWise                         HaskellWorks.Data.Bits.Broadword+                        HaskellWorks.Data.Bits.Broadword.Type+                        HaskellWorks.Data.Bits.Broadword.Word8+                        HaskellWorks.Data.Bits.Broadword.Word16+                        HaskellWorks.Data.Bits.Broadword.Word32+                        HaskellWorks.Data.Bits.Broadword.Word64                         HaskellWorks.Data.Bits.ElemFixedBitSize                         HaskellWorks.Data.Bits.FixedBitSize                         HaskellWorks.Data.Bits.FromBitTextByteString@@ -82,6 +87,7 @@                         HaskellWorks.Data.Bits.Types.Broadword                         HaskellWorks.Data.Bits.Types.Builtin                         HaskellWorks.Data.Bits.Word+                        HaskellWorks.Data.Bits.Word64                         HaskellWorks.Data.Bits.Writer.Storable   other-modules:        Paths_hw_bits   autogen-modules:      Paths_hw_bits
src/HaskellWorks/Data/Bits/Broadword.hs view
@@ -7,132 +7,17 @@ {-# LANGUAGE TypeFamilies          #-}  module HaskellWorks.Data.Bits.Broadword-  ( Broadword(..)-  , broadword-  , h-  , l-  , lsb-  , kBitDiff-  , kBitDiffPos-  , kBitDiffUnsafe+  {-# DEPRECATED "Import the relevant module instead" #-}+  ( BW.Broadword(..)+  , BW.broadword+  , W64.lsb+  , W64.h+  , W64.l+  , W64.kBitDiff+  , W64.kBitDiffPos+  , W64.kBitDiffUnsafe   ) where -import Control.DeepSeq-import Data.Word-import GHC.Generics-import HaskellWorks.Data.Bits.BitWise--import qualified Data.Bits as DB--newtype Broadword a = Broadword a deriving (Eq, Show, Generic, NFData)--broadword :: Broadword Word64 -> Word64-broadword (Broadword a) = a-{-# INLINE broadword #-}---- | Initialise all sub-words of size k where 'k' ∈ { 2, 4, 8, 16, 32, 64 } such that the lowest bit is set to 1 and all other bits are cleared.------ >>> import Numeric(showHex)--- >>> showHex (l 2) ""--- "5555555555555555"--- >>> showHex (l 4) ""--- "1111111111111111"--- >>> showHex (l 8) ""--- "101010101010101"--- >>> showHex (l 16) ""--- "1000100010001"--- >>> showHex (l 32) ""--- "100000001"--- >>> showHex (l 64) ""--- "1"-l :: Int -> Word64-l 2  = 0x5555555555555555-l 4  = 0x1111111111111111-l 8  = 0x0101010101010101-l 16 = 0x0001000100010001-l 32 = 0x0000000100000001-l 64 = 0x0000000000000001-l k  = error ("Invalid h k where k = " ++ show k)-{-# INLINE l #-}---- | Initialise all sub-words of size k where 'k' ∈ { 2, 4, 8, 16, 32, 64 } such that the highest bit is set to 1 and all other bits are cleared.------ >>> import Numeric(showHex)--- >>> showHex (h 2) ""--- "aaaaaaaaaaaaaaaa"--- >>> showHex (h 4) ""--- "8888888888888888"--- >>> showHex (h 8) ""--- "8080808080808080"--- >>> showHex (h 16) ""--- "8000800080008000"--- >>> showHex (h 32) ""--- "8000000080000000"--- >>> showHex (h 64) ""--- "8000000000000000"-h :: Int -> Word64-h 2  = 0xaaaaaaaaaaaaaaaa-h 4  = 0x8888888888888888-h 8  = 0x8080808080808080-h 16 = 0x8000800080008000-h 32 = 0x8000000080000000-h 64 = 0x8000000000000000-h k  = error ("Invalid h k where k = " ++ show k)-{-# INLINE h #-}---- | Broadword subtraction of sub-words of size 'k' where 'k' ∈ { 2, 4, 8, 16, 32, 64 }.------ The subtraction respects 2's complement so sub-words may be regarded as signed or unsigned words.------ >>> import Numeric(showHex)--- >>> showHex (kBitDiff 8 0x0807060504030201 0x0404030302020101) ""--- "403030202010100"--- >>> showHex (kBitDiff 8 0x0807060504030201 0x0102030405060708) ""--- "7050301fffdfbf9"--- >>> showHex (kBitDiff 8 0x20000000000000ff 0x10000000000000ff) ""--- "1000000000000000"-kBitDiff :: Int -> Word64 -> Word64 -> Word64-kBitDiff k x y = ((x .|. h k) - (y .&. comp (h k))) .^. ((x .^. comp y) .&. h k)-{-# INLINE kBitDiff #-}---- | Broadword subtraction of sub-words of size 'k' where 'k' ∈ { 2, 4, 8, 16, 32, 64 } where results are bounded from below by 0.------ >>> import Numeric(showHex)--- >>> showHex (kBitDiffPos 8 0x0807060504030201 0x0404030302020101) ""--- "403030202010100"--- >>> showHex (kBitDiffPos 8 0x0807060504030201 0x0102030405060708) ""--- "705030100000000"--- >>> showHex (kBitDiffPos 8 0x20000000000000ff 0x10000000000000ff) ""--- "1000000000000000"-kBitDiffPos :: Int -> Word64 -> Word64 -> Word64-kBitDiffPos k x y = let d = kBitDiff k x y in d .&. kBitDiff k 0 ((comp d .&. h 8) .>. fromIntegral (k - 1))-{-# INLINE kBitDiffPos #-}---- | Broadword subtraction of sub-words of size 'k' where 'k' ∈ { 2, 4, 8, 16, 32, 64 } where all the sub-words of 'x' and 'y' must--- not have the signed bit set for the result to be meaningful.------ >>> import Numeric(showHex)--- >>> showHex (kBitDiffUnsafe 8 0x0807060504030201 0x0404030302020101) ""--- "403030202010100"--- >>> showHex (kBitDiffUnsafe 8 0x0807060504030201 0x0102030405060708) ""--- "7050301fffdfbf9"--- >>> showHex (kBitDiffUnsafe 8 0x20000000000000ff 0x10000000000000ff) ""--- "1000000000000080"-kBitDiffUnsafe :: Int -> Word64 -> Word64 -> Word64-kBitDiffUnsafe k x y = ((x .|. h k) - y) .^. h k-{-# INLINE kBitDiffUnsafe #-}---- | Returns the position of the least significant bit (0-based).------ This is equivalent to 'DB.countTrailingZeros' except for when there are no bits set.  In which case--- return a word with all bits set.------ >>> lsb 8--- 3--- >>> lsb 1--- 0--- >>> lsb 0--- 18446744073709551615-lsb :: Word64 -> Word64-lsb w = let r = fromIntegral (DB.countTrailingZeros w) in r .|. negate ((r .>. 6) .&. 0x1)-{-# INLINE lsb #-}+import qualified HaskellWorks.Data.Bits.Broadword.Type   as BW+import qualified HaskellWorks.Data.Bits.Broadword.Word64 as W64+import qualified HaskellWorks.Data.Bits.Word64           as W64
+ src/HaskellWorks/Data/Bits/Broadword/Type.hs view
@@ -0,0 +1,22 @@+{-# LANGUAGE DeriveAnyClass        #-}+{-# LANGUAGE DeriveFunctor         #-}+{-# LANGUAGE DeriveGeneric         #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TypeFamilies          #-}++module HaskellWorks.Data.Bits.Broadword.Type+  ( Broadword(..)+  , broadword+  ) where++import Control.DeepSeq+import Data.Word+import GHC.Generics++newtype Broadword a = Broadword a deriving (Eq, Show, Functor, Generic, NFData)++broadword :: Broadword Word64 -> Word64+broadword (Broadword a) = a+{-# INLINE broadword #-}
+ src/HaskellWorks/Data/Bits/Broadword/Word16.hs view
@@ -0,0 +1,95 @@+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TypeFamilies          #-}++module HaskellWorks.Data.Bits.Broadword.Word16+  ( h+  , l+  , kBitDiff+  , kBitDiffPos+  , kBitDiffUnsafe+  ) where++import Data.Word+import HaskellWorks.Data.Bits.BitWise++-- | Initialise all sub-words of size k where 'k' ∈ { 2, 4, 8, 16 } such that the lowest bit is set to 1 and all other bits are cleared.+--+-- >>> import Numeric(showHex)+-- >>> showHex (l 2) ""+-- "5555"+-- >>> showHex (l 4) ""+-- "1111"+-- >>> showHex (l 8) ""+-- "101"+-- >>> showHex (l 16) ""+-- "1"+l :: Int -> Word16+l 2  = 0x5555+l 4  = 0x1111+l 8  = 0x0101+l 16 = 0x0001+l k  = error ("Invalid h k where k = " ++ show k)+{-# INLINE l #-}++-- | Initialise all sub-words of size k where 'k' ∈ { 2, 4, 8, 16 } such that the highest bit is set to 1 and all other bits are cleared.+--+-- >>> import Numeric(showHex)+-- >>> showHex (h 2) ""+-- "aaaa"+-- >>> showHex (h 4) ""+-- "8888"+-- >>> showHex (h 8) ""+-- "8080"+-- >>> showHex (h 16) ""+-- "8000"+h :: Int -> Word16+h 2  = 0xaaaa+h 4  = 0x8888+h 8  = 0x8080+h 16 = 0x8000+h k  = error ("Invalid h k where k = " ++ show k)+{-# INLINE h #-}++-- | Broadword subtraction of sub-words of size 'k' where 'k' ∈ { 2, 4, 8, 16 }.+--+-- The subtraction respects 2's complement so sub-words may be regarded as signed or unsigned words.+--+-- >>> import Numeric(showHex)+-- >>> showHex (kBitDiff 8 0x0201 0x0101) ""+-- "100"+-- >>> showHex (kBitDiff 8 0x0201 0x0102) ""+-- "1ff"+-- >>> showHex (kBitDiff 8 0x20ff 0x10ff) ""+-- "1000"+kBitDiff :: Int -> Word16 -> Word16 -> Word16+kBitDiff k x y = ((x .|. h k) - (y .&. comp (h k))) .^. ((x .^. comp y) .&. h k)+{-# INLINE kBitDiff #-}++-- | Broadword subtraction of sub-words of size 'k' where 'k' ∈ { 2, 4, 8, 16 } where results are bounded from below by 0.+--+-- >>> import Numeric(showHex)+-- >>> showHex (kBitDiffPos 8 0x0201 0x0101) ""+-- "100"+-- >>> showHex (kBitDiffPos 8 0x0201 0x0102) ""+-- "100"+-- >>> showHex (kBitDiffPos 8 0x20ff 0x10ff) ""+-- "1000"+kBitDiffPos :: Int -> Word16 -> Word16 -> Word16+kBitDiffPos k x y = let d = kBitDiff k x y in d .&. kBitDiff k 0 ((comp d .&. h 8) .>. fromIntegral (k - 1))+{-# INLINE kBitDiffPos #-}++-- | Broadword subtraction of sub-words of size 'k' where 'k' ∈ { 2, 4, 8, 16, 32, 64 } where all the sub-words of 'x' and 'y' must+-- not have the signed bit set for the result to be meaningful.+--+-- >>> import Numeric(showHex)+-- >>> showHex (kBitDiffUnsafe 8 0x0201 0x0101) ""+-- "100"+-- >>> showHex (kBitDiffUnsafe 8 0x0201 0x0102) ""+-- "1ff"+-- >>> showHex (kBitDiffUnsafe 8 0x20ff 0x10ff) "" -- produces nonsense in the last sub-word+-- "1080"+kBitDiffUnsafe :: Int -> Word16 -> Word16 -> Word16+kBitDiffUnsafe k x y = ((x .|. h k) - y) .^. h k+{-# INLINE kBitDiffUnsafe #-}
+ src/HaskellWorks/Data/Bits/Broadword/Word32.hs view
@@ -0,0 +1,101 @@+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TypeFamilies          #-}++module HaskellWorks.Data.Bits.Broadword.Word32+  ( h+  , l+  , kBitDiff+  , kBitDiffPos+  , kBitDiffUnsafe+  ) where++import Data.Word+import HaskellWorks.Data.Bits.BitWise++-- | Initialise all sub-words of size k where 'k' ∈ { 2, 4, 8, 16, 32 } such that the lowest bit is set to 1 and all other bits are cleared.+--+-- >>> import Numeric(showHex)+-- >>> showHex (l 2) ""+-- "55555555"+-- >>> showHex (l 4) ""+-- "11111111"+-- >>> showHex (l 8) ""+-- "1010101"+-- >>> showHex (l 16) ""+-- "10001"+-- >>> showHex (l 32) ""+-- "1"+l :: Int -> Word32+l 2  = 0x55555555+l 4  = 0x11111111+l 8  = 0x01010101+l 16 = 0x00010001+l 32 = 0x00000001+l k  = error ("Invalid h k where k = " ++ show k)+{-# INLINE l #-}++-- | Initialise all sub-words of size k where 'k' ∈ { 2, 4, 8, 16, 32 } such that the highest bit is set to 1 and all other bits are cleared.+--+-- >>> import Numeric(showHex)+-- >>> showHex (h 2) ""+-- "aaaaaaaa"+-- >>> showHex (h 4) ""+-- "88888888"+-- >>> showHex (h 8) ""+-- "80808080"+-- >>> showHex (h 16) ""+-- "80008000"+-- >>> showHex (h 32) ""+-- "80000000"+h :: Int -> Word32+h 2  = 0xaaaaaaaa+h 4  = 0x88888888+h 8  = 0x80808080+h 16 = 0x80008000+h 32 = 0x80000000+h k  = error ("Invalid h k where k = " ++ show k)+{-# INLINE h #-}++-- | Broadword subtraction of sub-words of size 'k' where 'k' ∈ { 2, 4, 8, 16, 32 }.+--+-- The subtraction respects 2's complement so sub-words may be regarded as signed or unsigned words.+--+-- >>> import Numeric(showHex)+-- >>> showHex (kBitDiff 8 0x04030201 0x02020101) ""+-- "2010100"+-- >>> showHex (kBitDiff 8 0x04030201 0x01020304) ""+-- "301fffd"+-- >>> showHex (kBitDiff 8 0x200000ff 0x100000ff) ""+-- "10000000"+kBitDiff :: Int -> Word32 -> Word32 -> Word32+kBitDiff k x y = ((x .|. h k) - (y .&. comp (h k))) .^. ((x .^. comp y) .&. h k)+{-# INLINE kBitDiff #-}++-- | Broadword subtraction of sub-words of size 'k' where 'k' ∈ { 2, 4, 8, 16, 32 } where results are bounded from below by 0.+--+-- >>> import Numeric(showHex)+-- >>> showHex (kBitDiffPos 8 0x04030201 0x02020101) ""+-- "2010100"+-- >>> showHex (kBitDiffPos 8 0x04030201 0x01020304) ""+-- "3010000"+-- >>> showHex (kBitDiffPos 8 0x200000ff 0x100000ff) "" -- produces nonsense in the last sub-word+-- "10000000"+kBitDiffPos :: Int -> Word32 -> Word32 -> Word32+kBitDiffPos k x y = let d = kBitDiff k x y in d .&. kBitDiff k 0 ((comp d .&. h 8) .>. fromIntegral (k - 1))+{-# INLINE kBitDiffPos #-}++-- | Broadword subtraction of sub-words of size 'k' where 'k' ∈ { 2, 4, 8, 16, 32 } where all the sub-words of 'x' and 'y' must+-- not have the signed bit set for the result to be meaningful.+--+-- >>> import Numeric(showHex)+-- >>> showHex (kBitDiffUnsafe 8 0x04030201 0x02020101) ""+-- "2010100"+-- >>> showHex (kBitDiffUnsafe 8 0x04030201 0x05060708) ""+-- "fffdfbf9"+-- >>> showHex (kBitDiffUnsafe 8 0x200000ff 0x100000ff) ""+-- "10000080"+kBitDiffUnsafe :: Int -> Word32 -> Word32 -> Word32+kBitDiffUnsafe k x y = ((x .|. h k) - y) .^. h k+{-# INLINE kBitDiffUnsafe #-}
+ src/HaskellWorks/Data/Bits/Broadword/Word64.hs view
@@ -0,0 +1,107 @@+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TypeFamilies          #-}++module HaskellWorks.Data.Bits.Broadword.Word64+  ( h+  , l+  , kBitDiff+  , kBitDiffPos+  , kBitDiffUnsafe+  ) where++import Data.Word+import HaskellWorks.Data.Bits.BitWise++-- | Initialise all sub-words of size k where 'k' ∈ { 2, 4, 8, 16, 32, 64 } such that the lowest bit is set to 1 and all other bits are cleared.+--+-- >>> import Numeric(showHex)+-- >>> showHex (l 2) ""+-- "5555555555555555"+-- >>> showHex (l 4) ""+-- "1111111111111111"+-- >>> showHex (l 8) ""+-- "101010101010101"+-- >>> showHex (l 16) ""+-- "1000100010001"+-- >>> showHex (l 32) ""+-- "100000001"+-- >>> showHex (l 64) ""+-- "1"+l :: Int -> Word64+l 2  = 0x5555555555555555+l 4  = 0x1111111111111111+l 8  = 0x0101010101010101+l 16 = 0x0001000100010001+l 32 = 0x0000000100000001+l 64 = 0x0000000000000001+l k  = error ("Invalid h k where k = " ++ show k)+{-# INLINE l #-}++-- | Initialise all sub-words of size k where 'k' ∈ { 2, 4, 8, 16, 32, 64 } such that the highest bit is set to 1 and all other bits are cleared.+--+-- >>> import Numeric(showHex)+-- >>> showHex (h 2) ""+-- "aaaaaaaaaaaaaaaa"+-- >>> showHex (h 4) ""+-- "8888888888888888"+-- >>> showHex (h 8) ""+-- "8080808080808080"+-- >>> showHex (h 16) ""+-- "8000800080008000"+-- >>> showHex (h 32) ""+-- "8000000080000000"+-- >>> showHex (h 64) ""+-- "8000000000000000"+h :: Int -> Word64+h 2  = 0xaaaaaaaaaaaaaaaa+h 4  = 0x8888888888888888+h 8  = 0x8080808080808080+h 16 = 0x8000800080008000+h 32 = 0x8000000080000000+h 64 = 0x8000000000000000+h k  = error ("Invalid h k where k = " ++ show k)+{-# INLINE h #-}++-- | Broadword subtraction of sub-words of size 'k' where 'k' ∈ { 2, 4, 8, 16, 32, 64 }.+--+-- The subtraction respects 2's complement so sub-words may be regarded as signed or unsigned words.+--+-- >>> import Numeric(showHex)+-- >>> showHex (kBitDiff 8 0x0807060504030201 0x0404030302020101) ""+-- "403030202010100"+-- >>> showHex (kBitDiff 8 0x0807060504030201 0x0102030405060708) ""+-- "7050301fffdfbf9"+-- >>> showHex (kBitDiff 8 0x20000000000000ff 0x10000000000000ff) ""+-- "1000000000000000"+kBitDiff :: Int -> Word64 -> Word64 -> Word64+kBitDiff k x y = ((x .|. h k) - (y .&. comp (h k))) .^. ((x .^. comp y) .&. h k)+{-# INLINE kBitDiff #-}++-- | Broadword subtraction of sub-words of size 'k' where 'k' ∈ { 2, 4, 8, 16, 32, 64 } where results are bounded from below by 0.+--+-- >>> import Numeric(showHex)+-- >>> showHex (kBitDiffPos 8 0x0807060504030201 0x0404030302020101) ""+-- "403030202010100"+-- >>> showHex (kBitDiffPos 8 0x0807060504030201 0x0102030405060708) ""+-- "705030100000000"+-- >>> showHex (kBitDiffPos 8 0x20000000000000ff 0x10000000000000ff) ""+-- "1000000000000000"+kBitDiffPos :: Int -> Word64 -> Word64 -> Word64+kBitDiffPos k x y = let d = kBitDiff k x y in d .&. kBitDiff k 0 ((comp d .&. h 8) .>. fromIntegral (k - 1))+{-# INLINE kBitDiffPos #-}++-- | Broadword subtraction of sub-words of size 'k' where 'k' ∈ { 2, 4, 8, 16, 32, 64 } where all the sub-words of 'x' and 'y' must+-- not have the signed bit set for the result to be meaningful.+--+-- >>> import Numeric(showHex)+-- >>> showHex (kBitDiffUnsafe 8 0x0807060504030201 0x0404030302020101) ""+-- "403030202010100"+-- >>> showHex (kBitDiffUnsafe 8 0x0807060504030201 0x0102030405060708) ""+-- "7050301fffdfbf9"+-- >>> showHex (kBitDiffUnsafe 8 0x20000000000000ff 0x10000000000000ff) "" -- produces nonsense in the last sub-word+-- "1000000000000080"+kBitDiffUnsafe :: Int -> Word64 -> Word64 -> Word64+kBitDiffUnsafe k x y = ((x .|. h k) - y) .^. h k+{-# INLINE kBitDiffUnsafe #-}
+ src/HaskellWorks/Data/Bits/Broadword/Word8.hs view
@@ -0,0 +1,89 @@+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TypeFamilies          #-}++module HaskellWorks.Data.Bits.Broadword.Word8+  ( h+  , l+  , kBitDiff+  , kBitDiffPos+  , kBitDiffUnsafe+  ) where++import Data.Word+import HaskellWorks.Data.Bits.BitWise++-- | Initialise all sub-words of size k where 'k' ∈ { 2, 4, 8, 16, 32 } such that the lowest bit is set to 1 and all other bits are cleared.+--+-- >>> import Numeric(showHex)+-- >>> showHex (l 2) ""+-- "55"+-- >>> showHex (l 4) ""+-- "11"+-- >>> showHex (l 8) ""+-- "1"+l :: Int -> Word8+l 2 = 0x55+l 4 = 0x11+l 8 = 0x01+l k = error ("Invalid h k where k = " ++ show k)+{-# INLINE l #-}++-- | Initialise all sub-words of size k where 'k' ∈ { 2, 4, 8, 16, 32 } such that the highest bit is set to 1 and all other bits are cleared.+--+-- >>> import Numeric(showHex)+-- >>> showHex (h 2) ""+-- "aa"+-- >>> showHex (h 4) ""+-- "88"+-- >>> showHex (h 8) ""+-- "80"+h :: Int -> Word8+h 2 = 0xaa+h 4 = 0x88+h 8 = 0x80+h k = error ("Invalid h k where k = " ++ show k)+{-# INLINE h #-}++-- | Broadword subtraction of sub-words of size 'k' where 'k' ∈ { 2, 4, 8 }.+--+-- The subtraction respects 2's complement so sub-words may be regarded as signed or unsigned words.+--+-- >>> import Numeric(showHex)+-- >>> showHex (kBitDiff 8 0x02 0x01) ""+-- "1"+-- >>> showHex (kBitDiff 8 0x01 0x02) ""+-- "ff"+-- >>> showHex (kBitDiff 8 0xff 0xff) ""+-- "0"+kBitDiff :: Int -> Word8 -> Word8 -> Word8+kBitDiff k x y = ((x .|. h k) - (y .&. comp (h k))) .^. ((x .^. comp y) .&. h k)+{-# INLINE kBitDiff #-}++-- | Broadword subtraction of sub-words of size 'k' where 'k' ∈ { 2, 4, 8 } where results are bounded from below by 0.+--+-- >>> import Numeric(showHex)+-- >>> showHex (kBitDiff 8 0x02 0x01) ""+-- "1"+-- >>> showHex (kBitDiff 8 0x01 0x02) ""+-- "ff"+-- >>> showHex (kBitDiff 8 0xff 0xff) ""+-- "0"+kBitDiffPos :: Int -> Word8 -> Word8 -> Word8+kBitDiffPos k x y = let d = kBitDiff k x y in d .&. kBitDiff k 0 ((comp d .&. h 8) .>. fromIntegral (k - 1))+{-# INLINE kBitDiffPos #-}++-- | Broadword subtraction of sub-words of size 'k' where 'k' ∈ { 2, 4, 8 } where all the sub-words of 'x' and 'y' must+-- not have the signed bit set for the result to be meaningful.+--+-- >>> import Numeric(showHex)+-- >>> showHex (kBitDiffUnsafe 8 0x02 0x01) ""+-- "1"+-- >>> showHex (kBitDiffUnsafe 8 0x01 0x02) ""+-- "ff"+-- >>> showHex (kBitDiffUnsafe 8 0xff 0xff) "" -- produces nonsense in the last sub-word+-- "80"+kBitDiffUnsafe :: Int -> Word8 -> Word8 -> Word8+kBitDiffUnsafe k x y = ((x .|. h k) - y) .^. h k+{-# INLINE kBitDiffUnsafe #-}
+ src/HaskellWorks/Data/Bits/Word64.hs view
@@ -0,0 +1,28 @@+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TypeFamilies          #-}++module HaskellWorks.Data.Bits.Word64+  ( lsb+  ) where++import Data.Word+import HaskellWorks.Data.Bits.BitWise++import qualified Data.Bits as DB++-- | Returns the position of the least significant bit (0-based).+--+-- This is equivalent to 'DB.countTrailingZeros' except for when there are no bits set.  In which case+-- return a word with all bits set.+--+-- >>> lsb 8+-- 3+-- >>> lsb 1+-- 0+-- >>> lsb 0+-- 18446744073709551615+lsb :: Word64 -> Word64+lsb w = let r = fromIntegral (DB.countTrailingZeros w) in r .|. negate ((r .>. 6) .&. 0x1)+{-# INLINE lsb #-}