{-# LANGUAGE CPP #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE DeriveDataTypeable #-}
module Basement.Types.Word256
( Word256(..)
, (+)
, (-)
, (*)
, quot
, rem
, bitwiseAnd
, bitwiseOr
, bitwiseXor
, complement
, shiftL
, shiftR
, rotateL
, rotateR
, popCount
, fromNatural
) where
import GHC.Prim hiding (word64ToWord#)
import qualified GHC.Prim
import GHC.Word
import GHC.Types
import qualified Prelude (fromInteger, show, Num(..), quot, rem, mod)
import Data.Bits hiding (complement, popCount, bit, testBit
, rotateL, rotateR, shiftL, shiftR)
import qualified Data.Bits as Bits
import Data.Function (on)
import Foreign.C
import Foreign.Ptr
import Foreign.Storable
import Basement.Compat.Base
import Basement.Compat.Natural
import Basement.Compat.Primitive (bool#)
import Basement.Numerical.Conversion
import Basement.Numerical.Number
#include "MachDeps.h"
data Word256 = Word256 {-# UNPACK #-} !Word64
{-# UNPACK #-} !Word64
{-# UNPACK #-} !Word64
{-# UNPACK #-} !Word64
deriving (Word256 -> Word256 -> Bool
(Word256 -> Word256 -> Bool)
-> (Word256 -> Word256 -> Bool) -> Eq Word256
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Word256 -> Word256 -> Bool
$c/= :: Word256 -> Word256 -> Bool
== :: Word256 -> Word256 -> Bool
$c== :: Word256 -> Word256 -> Bool
Eq, Typeable)
instance Show Word256 where
show :: Word256 -> String
show Word256
w = Natural -> String
forall a. Show a => a -> String
Prelude.show (Word256 -> Natural
forall a. IsNatural a => a -> Natural
toNatural Word256
w)
instance Enum Word256 where
toEnum :: Int -> Word256
toEnum Int
i = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
0 Word64
0 Word64
0 (Word64 -> Word256) -> Word64 -> Word256
forall a b. (a -> b) -> a -> b
$ Int64 -> Word64
int64ToWord64 (Int -> Int64
intToInt64 Int
i)
fromEnum :: Word256 -> Int
fromEnum (Word256 Word64
_ Word64
_ Word64
_ Word64
a0) = Word -> Int
wordToInt (Word64 -> Word
word64ToWord Word64
a0)
succ :: Word256 -> Word256
succ (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0)
| Word64
a0 Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
forall a. Bounded a => a
maxBound =
if Word64
a1 Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
forall a. Bounded a => a
maxBound
then if Word64
a2 Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
forall a. Bounded a => a
maxBound
then Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 (Word64 -> Word64
forall a. Enum a => a -> a
succ Word64
a3) Word64
0 Word64
0 Word64
0
else Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
a3 (Word64 -> Word64
forall a. Enum a => a -> a
succ Word64
a2) Word64
0 Word64
0
else Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
a3 Word64
a2 (Word64 -> Word64
forall a. Enum a => a -> a
succ Word64
a1) Word64
0
| Bool
otherwise = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
a3 Word64
a2 Word64
a1 (Word64 -> Word64
forall a. Enum a => a -> a
succ Word64
a0)
pred :: Word256 -> Word256
pred (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0)
| Word64
a0 Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
forall a. Bounded a => a
minBound =
if Word64
a1 Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
forall a. Bounded a => a
minBound
then if Word64
a2 Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
forall a. Bounded a => a
minBound
then Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 (Word64 -> Word64
forall a. Enum a => a -> a
pred Word64
a3) Word64
forall a. Bounded a => a
maxBound Word64
forall a. Bounded a => a
maxBound Word64
forall a. Bounded a => a
maxBound
else Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
a3 (Word64 -> Word64
forall a. Enum a => a -> a
pred Word64
a2) Word64
forall a. Bounded a => a
maxBound Word64
forall a. Bounded a => a
maxBound
else Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
a3 Word64
a2 (Word64 -> Word64
forall a. Enum a => a -> a
pred Word64
a1) Word64
forall a. Bounded a => a
maxBound
| Bool
otherwise = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
a3 Word64
a2 Word64
a1 (Word64 -> Word64
forall a. Enum a => a -> a
pred Word64
a0)
instance Bounded Word256 where
minBound :: Word256
minBound = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
forall a. Bounded a => a
minBound Word64
forall a. Bounded a => a
minBound Word64
forall a. Bounded a => a
minBound Word64
forall a. Bounded a => a
minBound
maxBound :: Word256
maxBound = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
forall a. Bounded a => a
maxBound Word64
forall a. Bounded a => a
maxBound Word64
forall a. Bounded a => a
maxBound Word64
forall a. Bounded a => a
maxBound
instance Ord Word256 where
compare :: Word256 -> Word256 -> Ordering
compare (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) (Word256 Word64
b3 Word64
b2 Word64
b1 Word64
b0) =
Word64 -> Word64 -> Ordering -> Ordering
forall a. Ord a => a -> a -> Ordering -> Ordering
compareEq Word64
a3 Word64
b3 (Ordering -> Ordering) -> Ordering -> Ordering
forall a b. (a -> b) -> a -> b
$ Word64 -> Word64 -> Ordering -> Ordering
forall a. Ord a => a -> a -> Ordering -> Ordering
compareEq Word64
a2 Word64
b2 (Ordering -> Ordering) -> Ordering -> Ordering
forall a b. (a -> b) -> a -> b
$ Word64 -> Word64 -> Ordering -> Ordering
forall a. Ord a => a -> a -> Ordering -> Ordering
compareEq Word64
a1 Word64
b1 (Ordering -> Ordering) -> Ordering -> Ordering
forall a b. (a -> b) -> a -> b
$ Word64 -> Word64 -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Word64
a0 Word64
b0
where compareEq :: a -> a -> Ordering -> Ordering
compareEq a
x a
y Ordering
next =
case a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare a
x a
y of
Ordering
EQ -> Ordering
next
Ordering
r -> Ordering
r
< :: Word256 -> Word256 -> Bool
(<) (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) (Word256 Word64
b3 Word64
b2 Word64
b1 Word64
b0) =
Word64 -> Word64 -> Bool -> Bool
forall a. Ord a => a -> a -> Bool -> Bool
compareLt Word64
a3 Word64
b3 (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Word64 -> Word64 -> Bool -> Bool
forall a. Ord a => a -> a -> Bool -> Bool
compareLt Word64
a2 Word64
b2 (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Word64 -> Word64 -> Bool -> Bool
forall a. Ord a => a -> a -> Bool -> Bool
compareLt Word64
a1 Word64
b1 (Word64
a0 Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
< Word64
b0)
where compareLt :: a -> a -> Bool -> Bool
compareLt a
x a
y Bool
next =
case a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare a
x a
y of
Ordering
EQ -> Bool
next
Ordering
r -> Ordering
r Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
LT
instance Storable Word256 where
sizeOf :: Word256 -> Int
sizeOf Word256
_ = Int
32
alignment :: Word256 -> Int
alignment Word256
_ = Int
32
peek :: Ptr Word256 -> IO Word256
peek Ptr Word256
p = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 (Word64 -> Word64 -> Word64 -> Word64 -> Word256)
-> IO Word64 -> IO (Word64 -> Word64 -> Word64 -> Word256)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr Word64 -> IO Word64
forall a. Storable a => Ptr a -> IO a
peek (Ptr Word256 -> Ptr Word64
forall a b. Ptr a -> Ptr b
castPtr Ptr Word256
p )
IO (Word64 -> Word64 -> Word64 -> Word256)
-> IO Word64 -> IO (Word64 -> Word64 -> Word256)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Ptr Word64 -> IO Word64
forall a. Storable a => Ptr a -> IO a
peek (Ptr Word256 -> Ptr Any
forall a b. Ptr a -> Ptr b
castPtr Ptr Word256
p Ptr Any -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
8)
IO (Word64 -> Word64 -> Word256)
-> IO Word64 -> IO (Word64 -> Word256)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Ptr Word64 -> IO Word64
forall a. Storable a => Ptr a -> IO a
peek (Ptr Word256 -> Ptr Any
forall a b. Ptr a -> Ptr b
castPtr Ptr Word256
p Ptr Any -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
16)
IO (Word64 -> Word256) -> IO Word64 -> IO Word256
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Ptr Word64 -> IO Word64
forall a. Storable a => Ptr a -> IO a
peek (Ptr Word256 -> Ptr Any
forall a b. Ptr a -> Ptr b
castPtr Ptr Word256
p Ptr Any -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
24)
poke :: Ptr Word256 -> Word256 -> IO ()
poke Ptr Word256
p (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) = do
Ptr Word64 -> Word64 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke (Ptr Word256 -> Ptr Word64
forall a b. Ptr a -> Ptr b
castPtr Ptr Word256
p ) Word64
a3
Ptr Word64 -> Word64 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke (Ptr Word256 -> Ptr Any
forall a b. Ptr a -> Ptr b
castPtr Ptr Word256
p Ptr Any -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
8 ) Word64
a2
Ptr Word64 -> Word64 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke (Ptr Word256 -> Ptr Any
forall a b. Ptr a -> Ptr b
castPtr Ptr Word256
p Ptr Any -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
16) Word64
a1
Ptr Word64 -> Word64 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke (Ptr Word256 -> Ptr Any
forall a b. Ptr a -> Ptr b
castPtr Ptr Word256
p Ptr Any -> Int -> Ptr Word64
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
24) Word64
a0
instance Integral Word256 where
fromInteger :: Integer -> Word256
fromInteger = Integer -> Word256
literal
instance HasNegation Word256 where
negate :: Word256 -> Word256
negate = Word256 -> Word256
complement
instance IsIntegral Word256 where
toInteger :: Word256 -> Integer
toInteger (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) =
(Word64 -> Integer
forall a. IsIntegral a => a -> Integer
toInteger Word64
a3 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`Bits.unsafeShiftL` Int
192) Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
Bits..|.
(Word64 -> Integer
forall a. IsIntegral a => a -> Integer
toInteger Word64
a2 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`Bits.unsafeShiftL` Int
128) Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
Bits..|.
(Word64 -> Integer
forall a. IsIntegral a => a -> Integer
toInteger Word64
a1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`Bits.unsafeShiftL` Int
64) Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
Bits..|.
Word64 -> Integer
forall a. IsIntegral a => a -> Integer
toInteger Word64
a0
instance IsNatural Word256 where
toNatural :: Word256 -> Natural
toNatural (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) =
(Word64 -> Natural
forall a. IsNatural a => a -> Natural
toNatural Word64
a3 Natural -> Int -> Natural
forall a. Bits a => a -> Int -> a
`Bits.unsafeShiftL` Int
192) Natural -> Natural -> Natural
forall a. Bits a => a -> a -> a
Bits..|.
(Word64 -> Natural
forall a. IsNatural a => a -> Natural
toNatural Word64
a2 Natural -> Int -> Natural
forall a. Bits a => a -> Int -> a
`Bits.unsafeShiftL` Int
128) Natural -> Natural -> Natural
forall a. Bits a => a -> a -> a
Bits..|.
(Word64 -> Natural
forall a. IsNatural a => a -> Natural
toNatural Word64
a1 Natural -> Int -> Natural
forall a. Bits a => a -> Int -> a
`Bits.unsafeShiftL` Int
64) Natural -> Natural -> Natural
forall a. Bits a => a -> a -> a
Bits..|.
Word64 -> Natural
forall a. IsNatural a => a -> Natural
toNatural Word64
a0
instance Prelude.Num Word256 where
abs :: Word256 -> Word256
abs Word256
w = Word256
w
signum :: Word256 -> Word256
signum w :: Word256
w@(Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0)
| Word64
a3 Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0 Bool -> Bool -> Bool
&& Word64
a2 Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0 Bool -> Bool -> Bool
&& Word64
a1 Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0 Bool -> Bool -> Bool
&& Word64
a0 Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0 = Word256
w
| Bool
otherwise = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
0 Word64
0 Word64
0 Word64
1
fromInteger :: Integer -> Word256
fromInteger = Integer -> Word256
literal
+ :: Word256 -> Word256 -> Word256
(+) = Word256 -> Word256 -> Word256
(+)
(-) = (-)
* :: Word256 -> Word256 -> Word256
(*) = Word256 -> Word256 -> Word256
(*)
instance Bits.Bits Word256 where
.&. :: Word256 -> Word256 -> Word256
(.&.) = Word256 -> Word256 -> Word256
bitwiseAnd
.|. :: Word256 -> Word256 -> Word256
(.|.) = Word256 -> Word256 -> Word256
bitwiseOr
xor :: Word256 -> Word256 -> Word256
xor = Word256 -> Word256 -> Word256
bitwiseXor
complement :: Word256 -> Word256
complement = Word256 -> Word256
complement
shiftL :: Word256 -> Int -> Word256
shiftL = Word256 -> Int -> Word256
shiftL
shiftR :: Word256 -> Int -> Word256
shiftR = Word256 -> Int -> Word256
shiftR
rotateL :: Word256 -> Int -> Word256
rotateL = Word256 -> Int -> Word256
rotateL
rotateR :: Word256 -> Int -> Word256
rotateR = Word256 -> Int -> Word256
rotateR
bitSize :: Word256 -> Int
bitSize Word256
_ = Int
256
bitSizeMaybe :: Word256 -> Maybe Int
bitSizeMaybe Word256
_ = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
256
isSigned :: Word256 -> Bool
isSigned Word256
_ = Bool
False
testBit :: Word256 -> Int -> Bool
testBit = Word256 -> Int -> Bool
testBit
bit :: Int -> Word256
bit = Int -> Word256
bit
popCount :: Word256 -> Int
popCount = Word256 -> Int
popCount
(+) :: Word256 -> Word256 -> Word256
#if WORD_SIZE_IN_BITS < 64
(+) = applyBiWordOnNatural (Prelude.+)
#else
+ :: Word256 -> Word256 -> Word256
(+) (Word256 (W64# Word#
a3) (W64# Word#
a2) (W64# Word#
a1) (W64# Word#
a0))
(Word256 (W64# Word#
b3) (W64# Word#
b2) (W64# Word#
b1) (W64# Word#
b0)) =
#if __GLASGOW_HASKELL__ >= 904
Word256 (W64# (wordToWord64# s3)) (W64# (wordToWord64# s2)) (W64# (wordToWord64# s1)) (W64# (wordToWord64# s0))
where
!(# c0, s0 #) = plusWord2# (GHC.Prim.word64ToWord# a0) (GHC.Prim.word64ToWord# b0)
!(# c1, s1 #) = plusWord3# (GHC.Prim.word64ToWord# a1) (GHC.Prim.word64ToWord# b1) (c0)
!(# c2, s2 #) = plusWord3# (GHC.Prim.word64ToWord# a2) (GHC.Prim.word64ToWord# b2) c1
!s3 = plusWord3NoCarry# (GHC.Prim.word64ToWord# a3) (GHC.Prim.word64ToWord# b3) c2
plusWord3NoCarry# a b c = plusWord# (plusWord# a b) c
plusWord3# a b c
| bool# (eqWord# carry 0##) = plusWord2# x c
| otherwise =
case plusWord2# x c of
(# carry2, x' #)
| bool# (eqWord# carry2 0##) -> (# carry, x' #)
| otherwise -> (# plusWord# carry carry2, x' #)
where
(# carry, x #) = plusWord2# a b
#else
Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 (Word# -> Word64
W64# Word#
s3) (Word# -> Word64
W64# Word#
s2) (Word# -> Word64
W64# Word#
s1) (Word# -> Word64
W64# Word#
s0)
where
!(# Word#
c0, Word#
s0 #) = Word# -> Word# -> (# Word#, Word# #)
plusWord2# Word#
a0 Word#
b0
!(# Word#
c1, Word#
s1 #) = Word# -> Word# -> Word# -> (# Word#, Word# #)
plusWord3# Word#
a1 Word#
b1 Word#
c0
!(# Word#
c2, Word#
s2 #) = Word# -> Word# -> Word# -> (# Word#, Word# #)
plusWord3# Word#
a2 Word#
b2 Word#
c1
!s3 :: Word#
s3 = Word# -> Word# -> Word# -> Word#
plusWord3NoCarry# Word#
a3 Word#
b3 Word#
c2
plusWord3NoCarry# :: Word# -> Word# -> Word# -> Word#
plusWord3NoCarry# Word#
a Word#
b Word#
c = Word# -> Word# -> Word#
plusWord# (Word# -> Word# -> Word#
plusWord# Word#
a Word#
b) Word#
c
plusWord3# :: Word# -> Word# -> Word# -> (# Word#, Word# #)
plusWord3# Word#
a Word#
b Word#
c
| Int# -> Bool
bool# (Word# -> Word# -> Int#
eqWord# Word#
carry Word#
0##) = Word# -> Word# -> (# Word#, Word# #)
plusWord2# Word#
x Word#
c
| Bool
otherwise =
case Word# -> Word# -> (# Word#, Word# #)
plusWord2# Word#
x Word#
c of
(# Word#
carry2, Word#
x' #)
| Int# -> Bool
bool# (Word# -> Word# -> Int#
eqWord# Word#
carry2 Word#
0##) -> (# Word#
carry, Word#
x' #)
| Bool
otherwise -> (# Word# -> Word# -> Word#
plusWord# Word#
carry Word#
carry2, Word#
x' #)
where
(# Word#
carry, Word#
x #) = Word# -> Word# -> (# Word#, Word# #)
plusWord2# Word#
a Word#
b
#endif
#endif
applyBiWordOnNatural :: (Natural -> Natural -> Natural)
-> Word256
-> Word256
-> Word256
applyBiWordOnNatural :: (Natural -> Natural -> Natural) -> Word256 -> Word256 -> Word256
applyBiWordOnNatural Natural -> Natural -> Natural
f = (Natural -> Word256
fromNatural (Natural -> Word256) -> (Word256 -> Natural) -> Word256 -> Word256
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
.) ((Word256 -> Natural) -> Word256 -> Word256)
-> (Word256 -> Word256 -> Natural) -> Word256 -> Word256 -> Word256
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (Natural -> Natural -> Natural
f (Natural -> Natural -> Natural)
-> (Word256 -> Natural) -> Word256 -> Word256 -> Natural
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Word256 -> Natural
forall a. IsNatural a => a -> Natural
toNatural)
(-) :: Word256 -> Word256 -> Word256
(-) Word256
a Word256
b
| Word256
a Word256 -> Word256 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word256
b = (Natural -> Natural -> Natural) -> Word256 -> Word256 -> Word256
applyBiWordOnNatural Natural -> Natural -> Natural
forall a. Num a => a -> a -> a
(Prelude.-) Word256
a Word256
b
| Bool
otherwise = Word256 -> Word256
complement ((Natural -> Natural -> Natural) -> Word256 -> Word256 -> Word256
applyBiWordOnNatural Natural -> Natural -> Natural
forall a. Num a => a -> a -> a
(Prelude.-) Word256
b Word256
a) Word256 -> Word256 -> Word256
+ Word256
1
(*) :: Word256 -> Word256 -> Word256
* :: Word256 -> Word256 -> Word256
(*) = (Natural -> Natural -> Natural) -> Word256 -> Word256 -> Word256
applyBiWordOnNatural Natural -> Natural -> Natural
forall a. Num a => a -> a -> a
(Prelude.*)
quot :: Word256 -> Word256 -> Word256
quot :: Word256 -> Word256 -> Word256
quot = (Natural -> Natural -> Natural) -> Word256 -> Word256 -> Word256
applyBiWordOnNatural Natural -> Natural -> Natural
forall a. Integral a => a -> a -> a
Prelude.quot
rem :: Word256 -> Word256 -> Word256
rem :: Word256 -> Word256 -> Word256
rem = (Natural -> Natural -> Natural) -> Word256 -> Word256 -> Word256
applyBiWordOnNatural Natural -> Natural -> Natural
forall a. Integral a => a -> a -> a
Prelude.rem
bitwiseAnd :: Word256 -> Word256 -> Word256
bitwiseAnd :: Word256 -> Word256 -> Word256
bitwiseAnd (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) (Word256 Word64
b3 Word64
b2 Word64
b1 Word64
b0) =
Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 (Word64
a3 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
Bits..&. Word64
b3) (Word64
a2 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
Bits..&. Word64
b2) (Word64
a1 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
Bits..&. Word64
b1) (Word64
a0 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
Bits..&. Word64
b0)
bitwiseOr :: Word256 -> Word256 -> Word256
bitwiseOr :: Word256 -> Word256 -> Word256
bitwiseOr (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) (Word256 Word64
b3 Word64
b2 Word64
b1 Word64
b0) =
Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 (Word64
a3 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
Bits..|. Word64
b3) (Word64
a2 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
Bits..|. Word64
b2) (Word64
a1 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
Bits..|. Word64
b1) (Word64
a0 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
Bits..|. Word64
b0)
bitwiseXor :: Word256 -> Word256 -> Word256
bitwiseXor :: Word256 -> Word256 -> Word256
bitwiseXor (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) (Word256 Word64
b3 Word64
b2 Word64
b1 Word64
b0) =
Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 (Word64
a3 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`Bits.xor` Word64
b3) (Word64
a2 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`Bits.xor` Word64
b2) (Word64
a1 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`Bits.xor` Word64
b1) (Word64
a0 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`Bits.xor` Word64
b0)
complement :: Word256 -> Word256
complement :: Word256 -> Word256
complement (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) =
Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 (Word64 -> Word64
forall a. Bits a => a -> a
Bits.complement Word64
a3) (Word64 -> Word64
forall a. Bits a => a -> a
Bits.complement Word64
a2) (Word64 -> Word64
forall a. Bits a => a -> a
Bits.complement Word64
a1) (Word64 -> Word64
forall a. Bits a => a -> a
Bits.complement Word64
a0)
popCount :: Word256 -> Int
popCount :: Word256 -> Int
popCount (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) =
Word64 -> Int
forall a. Bits a => a -> Int
Bits.popCount Word64
a3 Int -> Int -> Int
forall a. Num a => a -> a -> a
Prelude.+
Word64 -> Int
forall a. Bits a => a -> Int
Bits.popCount Word64
a2 Int -> Int -> Int
forall a. Num a => a -> a -> a
Prelude.+
Word64 -> Int
forall a. Bits a => a -> Int
Bits.popCount Word64
a1 Int -> Int -> Int
forall a. Num a => a -> a -> a
Prelude.+
Word64 -> Int
forall a. Bits a => a -> Int
Bits.popCount Word64
a0
shiftL :: Word256 -> Int -> Word256
shiftL :: Word256 -> Int -> Word256
shiftL w :: Word256
w@(Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) Int
n
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
|| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
255 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
0 Word64
0 Word64
0 Word64
0
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Word256
w
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
64 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
a2 Word64
a1 Word64
a0 Word64
0
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
128 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
a1 Word64
a0 Word64
0 Word64
0
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
192 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
a0 Word64
0 Word64
0 Word64
0
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
64 = Word64 -> Word64 -> Word64 -> Word64 -> Int -> Word256
mkWordShift Word64
a3 Word64
a2 Word64
a1 Word64
a0 Int
n
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
128 = Word64 -> Word64 -> Word64 -> Word64 -> Int -> Word256
mkWordShift Word64
a2 Word64
a1 Word64
a0 Word64
0 (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
Prelude.- Int
64)
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
192 = Word64 -> Word64 -> Word64 -> Word64 -> Int -> Word256
mkWordShift Word64
a1 Word64
a0 Word64
0 Word64
0 (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
Prelude.- Int
128)
| Bool
otherwise = Word64 -> Word64 -> Word64 -> Word64 -> Int -> Word256
mkWordShift Word64
a0 Word64
0 Word64
0 Word64
0 (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
Prelude.- Int
192)
where
mkWordShift :: Word64 -> Word64 -> Word64 -> Word64 -> Int -> Word256
mkWordShift :: Word64 -> Word64 -> Word64 -> Word64 -> Int -> Word256
mkWordShift Word64
w Word64
x Word64
y Word64
z Int
s =
Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 (Word64 -> Int -> Word64 -> Int -> Word64
comb64 Word64
w Int
s Word64
x Int
s') (Word64 -> Int -> Word64 -> Int -> Word64
comb64 Word64
x Int
s Word64
y Int
s') (Word64 -> Int -> Word64 -> Int -> Word64
comb64 Word64
y Int
s Word64
z Int
s') (Word64
z Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`Bits.unsafeShiftL` Int
s)
where s' :: Int
s' = Int -> Int
inv64 Int
s
shiftR :: Word256 -> Int -> Word256
shiftR :: Word256 -> Int -> Word256
shiftR w :: Word256
w@(Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) Int
n
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
|| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
255 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
0 Word64
0 Word64
0 Word64
0
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Word256
w
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
64 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
0 Word64
a3 Word64
a2 Word64
a1
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
128 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
0 Word64
0 Word64
a3 Word64
a2
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
192 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
0 Word64
0 Word64
0 Word64
a3
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
64 = Word64 -> Word64 -> Word64 -> Word64 -> Int -> Word256
mkWordShift Word64
a3 Word64
a2 Word64
a1 Word64
a0 Int
n
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
128 = Word64 -> Word64 -> Word64 -> Word64 -> Int -> Word256
mkWordShift Word64
0 Word64
a3 Word64
a2 Word64
a1 (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
Prelude.- Int
64)
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
192 = Word64 -> Word64 -> Word64 -> Word64 -> Int -> Word256
mkWordShift Word64
0 Word64
0 Word64
a3 Word64
a2 (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
Prelude.- Int
128)
| Bool
otherwise = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
0 Word64
0 Word64
0 (Word64
a3 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`Bits.unsafeShiftR` (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
Prelude.- Int
192))
where
mkWordShift :: Word64 -> Word64 -> Word64 -> Word64 -> Int -> Word256
mkWordShift :: Word64 -> Word64 -> Word64 -> Word64 -> Int -> Word256
mkWordShift Word64
w Word64
x Word64
y Word64
z Int
s =
Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 (Word64
w Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`Bits.unsafeShiftR` Int
s) (Word64 -> Int -> Word64 -> Int -> Word64
comb64 Word64
w Int
s' Word64
x Int
s) (Word64 -> Int -> Word64 -> Int -> Word64
comb64 Word64
x Int
s' Word64
y Int
s) (Word64 -> Int -> Word64 -> Int -> Word64
comb64 Word64
y Int
s' Word64
z Int
s)
where s' :: Int
s' = Int -> Int
inv64 Int
s
rotateL :: Word256 -> Int -> Word256
rotateL :: Word256 -> Int -> Word256
rotateL (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) Int
n'
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
192 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
a0 Word64
a3 Word64
a2 Word64
a1
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
128 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
a1 Word64
a0 Word64
a3 Word64
a2
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
64 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
a2 Word64
a1 Word64
a0 Word64
a3
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
64 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 (Word64 -> Int -> Word64 -> Int -> Word64
comb64 Word64
a3 Int
n Word64
a2 (Int -> Int
inv64 Int
n)) (Word64 -> Int -> Word64 -> Int -> Word64
comb64 Word64
a2 Int
n Word64
a1 (Int -> Int
inv64 Int
n))
(Word64 -> Int -> Word64 -> Int -> Word64
comb64 Word64
a1 Int
n Word64
a0 (Int -> Int
inv64 Int
n)) (Word64 -> Int -> Word64 -> Int -> Word64
comb64 Word64
a0 Int
n Word64
a3 (Int -> Int
inv64 Int
n))
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
128 = let n :: Int
n = Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
Prelude.- Int
64 in Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256
(Word64 -> Int -> Word64 -> Int -> Word64
comb64 Word64
a2 Int
n Word64
a1 (Int -> Int
inv64 Int
n)) (Word64 -> Int -> Word64 -> Int -> Word64
comb64 Word64
a1 Int
n Word64
a0 (Int -> Int
inv64 Int
n))
(Word64 -> Int -> Word64 -> Int -> Word64
comb64 Word64
a0 Int
n Word64
a3 (Int -> Int
inv64 Int
n)) (Word64 -> Int -> Word64 -> Int -> Word64
comb64 Word64
a3 Int
n Word64
a2 (Int -> Int
inv64 Int
n))
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
192 = let n :: Int
n = Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
Prelude.- Int
128 in Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256
(Word64 -> Int -> Word64 -> Int -> Word64
comb64 Word64
a1 Int
n Word64
a0 (Int -> Int
inv64 Int
n)) (Word64 -> Int -> Word64 -> Int -> Word64
comb64 Word64
a0 Int
n Word64
a3 (Int -> Int
inv64 Int
n))
(Word64 -> Int -> Word64 -> Int -> Word64
comb64 Word64
a3 Int
n Word64
a2 (Int -> Int
inv64 Int
n)) (Word64 -> Int -> Word64 -> Int -> Word64
comb64 Word64
a2 Int
n Word64
a1 (Int -> Int
inv64 Int
n))
| Bool
otherwise = let n :: Int
n = Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
Prelude.- Int
192 in Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256
(Word64 -> Int -> Word64 -> Int -> Word64
comb64 Word64
a0 Int
n Word64
a3 (Int -> Int
inv64 Int
n)) (Word64 -> Int -> Word64 -> Int -> Word64
comb64 Word64
a3 Int
n Word64
a2 (Int -> Int
inv64 Int
n))
(Word64 -> Int -> Word64 -> Int -> Word64
comb64 Word64
a2 Int
n Word64
a1 (Int -> Int
inv64 Int
n)) (Word64 -> Int -> Word64 -> Int -> Word64
comb64 Word64
a1 Int
n Word64
a0 (Int -> Int
inv64 Int
n))
where
n :: Int
n :: Int
n | Int
n' Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 = Int
n' Int -> Int -> Int
forall a. Integral a => a -> a -> a
`Prelude.mod` Int
256
| Bool
otherwise = Int
256 Int -> Int -> Int
forall a. Num a => a -> a -> a
Prelude.- (Int
n' Int -> Int -> Int
forall a. Integral a => a -> a -> a
`Prelude.mod` Int
256)
rotateR :: Word256 -> Int -> Word256
rotateR :: Word256 -> Int -> Word256
rotateR Word256
w Int
n = Word256 -> Int -> Word256
rotateL Word256
w (Int
256 Int -> Int -> Int
forall a. Num a => a -> a -> a
Prelude.- Int
n)
inv64 :: Int -> Int
inv64 :: Int -> Int
inv64 Int
i = Int
64 Int -> Int -> Int
forall a. Num a => a -> a -> a
Prelude.- Int
i
comb64 :: Word64 -> Int -> Word64 -> Int -> Word64
comb64 :: Word64 -> Int -> Word64 -> Int -> Word64
comb64 Word64
x Int
i Word64
y Int
j =
(Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`Bits.unsafeShiftL` Int
i) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. (Word64
y Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`Bits.unsafeShiftR` Int
j)
testBit :: Word256 -> Int -> Bool
testBit :: Word256 -> Int -> Bool
testBit (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) Int
n
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
|| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
255 = Bool
False
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
191 = Word64 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
Bits.testBit Word64
a3 (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
Prelude.- Int
192)
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
127 = Word64 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
Bits.testBit Word64
a2 (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
Prelude.- Int
128)
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
63 = Word64 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
Bits.testBit Word64
a1 (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
Prelude.- Int
64)
| Bool
otherwise = Word64 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
Bits.testBit Word64
a0 Int
n
bit :: Int -> Word256
bit :: Int -> Word256
bit Int
n
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
|| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
255 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
0 Word64
0 Word64
0 Word64
0
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
191 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 (Int -> Word64
forall a. Bits a => Int -> a
Bits.bit (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
Prelude.- Int
192)) Word64
0 Word64
0 Word64
0
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
127 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
0 (Int -> Word64
forall a. Bits a => Int -> a
Bits.bit (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
Prelude.- Int
128)) Word64
0 Word64
0
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
63 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
0 Word64
0 (Int -> Word64
forall a. Bits a => Int -> a
Bits.bit (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
Prelude.- Int
64)) Word64
0
| Bool
otherwise = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
0 Word64
0 Word64
0 (Int -> Word64
forall a. Bits a => Int -> a
Bits.bit Int
n)
literal :: Integer -> Word256
literal :: Integer -> Word256
literal Integer
i = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256
(Integer -> Word64
forall a. Num a => Integer -> a
Prelude.fromInteger (Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`Bits.unsafeShiftR` Int
192))
(Integer -> Word64
forall a. Num a => Integer -> a
Prelude.fromInteger (Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`Bits.unsafeShiftR` Int
128))
(Integer -> Word64
forall a. Num a => Integer -> a
Prelude.fromInteger (Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`Bits.unsafeShiftR` Int
64))
(Integer -> Word64
forall a. Num a => Integer -> a
Prelude.fromInteger Integer
i)
fromNatural :: Natural -> Word256
fromNatural :: Natural -> Word256
fromNatural Natural
n = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256
(Integer -> Word64
forall a. Num a => Integer -> a
Prelude.fromInteger (Natural -> Integer
naturalToInteger Natural
n Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`Bits.unsafeShiftR` Int
192))
(Integer -> Word64
forall a. Num a => Integer -> a
Prelude.fromInteger (Natural -> Integer
naturalToInteger Natural
n Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`Bits.unsafeShiftR` Int
128))
(Integer -> Word64
forall a. Num a => Integer -> a
Prelude.fromInteger (Natural -> Integer
naturalToInteger Natural
n Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`Bits.unsafeShiftR` Int
64))
(Integer -> Word64
forall a. Num a => Integer -> a
Prelude.fromInteger (Integer -> Word64) -> Integer -> Word64
forall a b. (a -> b) -> a -> b
$ Natural -> Integer
naturalToInteger Natural
n)