{-# 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
l :: Int -> Word64
l :: Int -> Word64
l Int
2 = Word64
0x5555555555555555
l Int
4 = Word64
0x1111111111111111
l Int
8 = Word64
0x0101010101010101
l Int
16 = Word64
0x0001000100010001
l Int
32 = Word64
0x0000000100000001
l Int
64 = Word64
0x0000000000000001
l Int
k = [Char] -> Word64
forall a. HasCallStack => [Char] -> a
error ([Char]
"Invalid h k where k = " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
k)
{-# INLINE l #-}
h :: Int -> Word64
h :: Int -> Word64
h Int
2 = Word64
0xaaaaaaaaaaaaaaaa
h Int
4 = Word64
0x8888888888888888
h Int
8 = Word64
0x8080808080808080
h Int
16 = Word64
0x8000800080008000
h Int
32 = Word64
0x8000000080000000
h Int
64 = Word64
0x8000000000000000
h Int
k = [Char] -> Word64
forall a. HasCallStack => [Char] -> a
error ([Char]
"Invalid h k where k = " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
k)
{-# INLINE h #-}
kBitDiff :: Int -> Word64 -> Word64 -> Word64
kBitDiff :: Int -> Word64 -> Word64 -> Word64
kBitDiff Int
k Word64
x Word64
y = ((Word64
x Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.|. Int -> Word64
h Int
k) Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- (Word64
y Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Word64 -> Word64
forall a. BitWise a => a -> a
comp (Int -> Word64
h Int
k))) Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.^. ((Word64
x Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.^. Word64 -> Word64
forall a. BitWise a => a -> a
comp Word64
y) Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Int -> Word64
h Int
k)
{-# INLINE kBitDiff #-}
kBitDiffPos :: Int -> Word64 -> Word64 -> Word64
kBitDiffPos :: Int -> Word64 -> Word64 -> Word64
kBitDiffPos Int
k Word64
x Word64
y =
let d :: Word64
d = Int -> Word64 -> Word64 -> Word64
kBitDiff Int
k Word64
x Word64
y in
let s :: Word64
s = Int -> Word64 -> Word64 -> Word64
kBitDiff Int
k Word64
0 ((Word64 -> Word64
forall a. BitWise a => a -> a
comp Word64
d Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Int -> Word64
h Int
k) Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>. Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)) in
let r :: Word64
r = Word64
d Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Word64
s in
Word64
r
{-# INLINE kBitDiffPos #-}
kBitDiffUnsafe :: Int -> Word64 -> Word64 -> Word64
kBitDiffUnsafe :: Int -> Word64 -> Word64 -> Word64
kBitDiffUnsafe Int
k Word64
x Word64
y = ((Word64
x Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.|. Int -> Word64
h Int
k) Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
y) Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.^. Int -> Word64
h Int
k
{-# INLINE kBitDiffUnsafe #-}