diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2016 John Ky
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,4 @@
+# hw-excess
+[![0.0-branch](https://circleci.com/gh/haskell-works/hw-excess/tree/0.0-branch.svg?style=svg)](https://circleci.com/gh/haskell-works/hw-excess/tree/0.0-branch)
+
+Rank and select operations.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/hw-excess.cabal b/hw-excess.cabal
new file mode 100644
--- /dev/null
+++ b/hw-excess.cabal
@@ -0,0 +1,51 @@
+name:                   hw-excess
+version:                0.0.0.1
+synopsis:               Conduits for tokenizing streams.
+description:            Please see README.md
+homepage:               http://github.com/haskell-works/hw-excess#readme
+license:                MIT
+license-file:           LICENSE
+author:                 John Ky
+maintainer:             newhoggy@gmail.com
+copyright:              2016 John Ky
+category:               Data, Conduit
+build-type:             Simple
+extra-source-files:     README.md
+cabal-version:          >= 1.22
+
+library
+  hs-source-dirs:       src
+  exposed-modules:      HaskellWorks.Data.Excess
+                      , HaskellWorks.Data.Excess.Excess0
+                      , HaskellWorks.Data.Excess.Excess1
+                      , HaskellWorks.Data.Excess.MinMaxExcess0
+                      , HaskellWorks.Data.Excess.MinMaxExcess1
+  build-depends:        base                          >= 4          && < 5
+                      , hw-bits                       >= 0.3.0.0
+                      , hw-prim                       >= 0.3.0.5
+                      , hw-rankselect-base            >= 0.1.0.0
+                      , safe
+                      , vector
+
+  default-language:     Haskell2010
+  ghc-options:          -Wall -O2 -msse4.2
+
+test-suite hw-excess-test
+  type:                 exitcode-stdio-1.0
+  hs-source-dirs:       test
+  main-is:              Spec.hs
+  other-modules:        HaskellWorks.Data.Excess.MinMaxExcess0Spec
+                      , HaskellWorks.Data.Excess.MinMaxExcess1Spec
+  build-depends:        base                          >= 4          && < 5
+                      , hspec
+                      , hw-bits                       >= 0.3.0.0
+                      , hw-prim                       >= 0.3.0.5
+                      , hw-excess
+                      , QuickCheck
+                      , vector
+  ghc-options:          -threaded -rtsopts -with-rtsopts=-N -Wall
+  default-language:     Haskell2010
+
+source-repository head
+  type:     git
+  location: https://github.com/haskell-works/hw-excess
diff --git a/src/HaskellWorks/Data/Excess.hs b/src/HaskellWorks/Data/Excess.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Excess.hs
@@ -0,0 +1,6 @@
+module HaskellWorks.Data.Excess
+  ( module X
+  ) where
+
+import HaskellWorks.Data.Excess.Excess0 as X
+import HaskellWorks.Data.Excess.Excess1 as X
diff --git a/src/HaskellWorks/Data/Excess/Excess0.hs b/src/HaskellWorks/Data/Excess/Excess0.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Excess/Excess0.hs
@@ -0,0 +1,46 @@
+{-# LANGUAGE FlexibleInstances     #-}
+
+module HaskellWorks.Data.Excess.Excess0
+    ( Excess0(..)
+    ) where
+
+import           Data.Word
+import qualified Data.Vector.Storable as DVS
+import           HaskellWorks.Data.Positioning
+import           HaskellWorks.Data.RankSelect.Base.Rank0
+import           HaskellWorks.Data.RankSelect.Base.Rank1
+
+class Excess0 v where
+  excess0 :: v -> Count -> Int
+
+instance Excess0 Word8 where
+  excess0 v c = fromIntegral (rank0 v c) - fromIntegral (rank1 v c)
+  {-# INLINE excess0 #-}
+
+instance Excess0 Word16 where
+  excess0 v c = fromIntegral (rank0 v c) - fromIntegral (rank1 v c)
+  {-# INLINE excess0 #-}
+
+instance Excess0 Word32 where
+  excess0 v c = fromIntegral (rank0 v c) - fromIntegral (rank1 v c)
+  {-# INLINE excess0 #-}
+
+instance Excess0 Word64 where
+  excess0 v c = fromIntegral (rank0 v c) - fromIntegral (rank1 v c)
+  {-# INLINE excess0 #-}
+
+instance Excess0 (DVS.Vector Word8) where
+  excess0 v c = fromIntegral (rank0 v c) - fromIntegral (rank1 v c)
+  {-# INLINE excess0 #-}
+
+instance Excess0 (DVS.Vector Word16) where
+  excess0 v c = fromIntegral (rank0 v c) - fromIntegral (rank1 v c)
+  {-# INLINE excess0 #-}
+
+instance Excess0 (DVS.Vector Word32) where
+  excess0 v c = fromIntegral (rank0 v c) - fromIntegral (rank1 v c)
+  {-# INLINE excess0 #-}
+
+instance Excess0 (DVS.Vector Word64) where
+  excess0 v c = fromIntegral (rank0 v c) - fromIntegral (rank1 v c)
+  {-# INLINE excess0 #-}
diff --git a/src/HaskellWorks/Data/Excess/Excess1.hs b/src/HaskellWorks/Data/Excess/Excess1.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Excess/Excess1.hs
@@ -0,0 +1,46 @@
+{-# LANGUAGE FlexibleInstances     #-}
+
+module HaskellWorks.Data.Excess.Excess1
+    ( Excess1(..)
+    ) where
+
+import           Data.Word
+import qualified Data.Vector.Storable as DVS
+import           HaskellWorks.Data.Positioning
+import           HaskellWorks.Data.RankSelect.Base.Rank0
+import           HaskellWorks.Data.RankSelect.Base.Rank1
+
+class Excess1 v where
+  excess1 :: v -> Count -> Int
+
+instance Excess1 Word8 where
+  excess1 v c = fromIntegral (rank1 v c) - fromIntegral (rank0 v c)
+  {-# INLINE excess1 #-}
+
+instance Excess1 Word16 where
+  excess1 v c = fromIntegral (rank1 v c) - fromIntegral (rank0 v c)
+  {-# INLINE excess1 #-}
+
+instance Excess1 Word32 where
+  excess1 v c = fromIntegral (rank1 v c) - fromIntegral (rank0 v c)
+  {-# INLINE excess1 #-}
+
+instance Excess1 Word64 where
+  excess1 v c = fromIntegral (rank1 v c) - fromIntegral (rank0 v c)
+  {-# INLINE excess1 #-}
+
+instance Excess1 (DVS.Vector Word8) where
+  excess1 v c = fromIntegral (rank1 v c) - fromIntegral (rank0 v c)
+  {-# INLINE excess1 #-}
+
+instance Excess1 (DVS.Vector Word16) where
+  excess1 v c = fromIntegral (rank1 v c) - fromIntegral (rank0 v c)
+  {-# INLINE excess1 #-}
+
+instance Excess1 (DVS.Vector Word32) where
+  excess1 v c = fromIntegral (rank1 v c) - fromIntegral (rank0 v c)
+  {-# INLINE excess1 #-}
+
+instance Excess1 (DVS.Vector Word64) where
+  excess1 v c = fromIntegral (rank1 v c) - fromIntegral (rank0 v c)
+  {-# INLINE excess1 #-}
diff --git a/src/HaskellWorks/Data/Excess/MinMaxExcess0.hs b/src/HaskellWorks/Data/Excess/MinMaxExcess0.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Excess/MinMaxExcess0.hs
@@ -0,0 +1,174 @@
+{-# LANGUAGE FlexibleInstances          #-}
+
+module HaskellWorks.Data.Excess.MinMaxExcess0
+  ( MinMaxExcess0(..)
+  , MaxExcess
+  , MinExcess
+  ) where
+
+import qualified Data.Vector.Storable                 as DVS
+import           Data.Word
+import           HaskellWorks.Data.Bits.BitWise
+import           HaskellWorks.Data.Bits.FixedBitSize
+import           HaskellWorks.Data.Naive
+
+type MinExcess = Int
+type MaxExcess = Int
+type Excess    = Int
+
+class MinMaxExcess0 a where
+  minMaxExcess0 :: a -> (MinExcess, Excess, MaxExcess)
+
+instance MinMaxExcess0 [Bool] where
+  minMaxExcess0 = go 0 0 0
+    where go minE maxE e (x:xs)                   = let ne = if x then e - 1 else e + 1 in
+                                                        go (minE `min` ne) (maxE `max` ne) ne xs
+          go minE maxE e _                        = (minE, e, maxE)
+  {-# INLINE minMaxExcess0 #-}
+
+instance MinMaxExcess0 (Naive Word8) where
+  minMaxExcess0 = go 0 0 0 0 . naive
+    where go minE maxE e n w | n < fixedBitSize w = let ne = if w .?. fromIntegral n then e - 1 else e + 1 in
+                                                        go (minE `min` ne) (maxE `max` ne) ne (n + 1) w
+          go minE maxE e _ _                       = (minE, e, maxE)
+  {-# INLINE minMaxExcess0 #-}
+
+instance MinMaxExcess0 (Naive Word16) where
+  minMaxExcess0 = go 0 0 0 0 . naive
+    where go minE maxE e n w | n < fixedBitSize w = let ne = if w .?. fromIntegral n then e - 1 else e + 1 in
+                                                        go (minE `min` ne) (maxE `max` ne) ne (n + 1) w
+          go minE maxE e _ _                      = (minE, e, maxE)
+  {-# INLINE minMaxExcess0 #-}
+
+instance MinMaxExcess0 (Naive Word32) where
+  minMaxExcess0 = go 0 0 0 0 . naive
+    where go minE maxE e n w | n < fixedBitSize w = let ne = if w .?. fromIntegral n then e - 1 else e + 1 in
+                                                        go (minE `min` ne) (maxE `max` ne) ne (n + 1) w
+          go minE maxE e _ _                      = (minE, e, maxE)
+  {-# INLINE minMaxExcess0 #-}
+
+instance MinMaxExcess0 (Naive Word64) where
+  minMaxExcess0 = go 0 0 0 0 . naive
+    where go minE maxE e n w | n < fixedBitSize w = let ne = if w .?. fromIntegral n then e - 1 else e + 1 in
+                                                        go (minE `min` ne) (maxE `max` ne) ne (n + 1) w
+          go minE maxE e _ _                      = (minE, e, maxE)
+  {-# INLINE minMaxExcess0 #-}
+
+instance MinMaxExcess0 Word8 where
+  minMaxExcess0 w = ( word8Excess0Min DVS.! fromIntegral w
+                    , word8Excess0    DVS.! fromIntegral w
+                    , word8Excess0Max DVS.! fromIntegral w
+                    )
+  {-# INLINE minMaxExcess0 #-}
+
+instance MinMaxExcess0 Word16 where
+  minMaxExcess0 w = ( minExcessA `min` (minExcessB + allExcessA)
+                    , allExcessA + allExcessB
+                    , maxExcessA `max` (maxExcessB + allExcessA))
+    where (minExcessA, allExcessA, maxExcessA) = minMaxExcess0 (fromIntegral  w        :: Word8)
+          (minExcessB, allExcessB, maxExcessB) = minMaxExcess0 (fromIntegral (w .>. 8) :: Word8)
+  {-# INLINE minMaxExcess0 #-}
+
+instance MinMaxExcess0 Word32 where
+  minMaxExcess0 w = ( minExcessA `min` (minExcessB + allExcessA)
+                    , allExcessA + allExcessB
+                    , maxExcessA `max` (maxExcessB + allExcessA))
+    where (minExcessA, allExcessA, maxExcessA) = minMaxExcess0 (fromIntegral  w         :: Word16)
+          (minExcessB, allExcessB, maxExcessB) = minMaxExcess0 (fromIntegral (w .>. 16) :: Word16)
+  {-# INLINE minMaxExcess0 #-}
+
+instance MinMaxExcess0 Word64 where
+  minMaxExcess0 w = ( minExcessA `min` (minExcessB + allExcessA)
+                    , allExcessA + allExcessB
+                    , maxExcessA `max` (maxExcessB + allExcessA))
+    where (minExcessA, allExcessA, maxExcessA) = minMaxExcess0 (fromIntegral  w         :: Word32)
+          (minExcessB, allExcessB, maxExcessB) = minMaxExcess0 (fromIntegral (w .>. 32) :: Word32)
+  {-# INLINE minMaxExcess0 #-}
+
+instance MinMaxExcess0 (DVS.Vector Word8) where
+  minMaxExcess0 = DVS.foldl gen (0, 0, 0)
+    where gen :: (MinExcess, Excess, MaxExcess) -> Word8 -> (MinExcess, Excess, MaxExcess)
+          gen (minE, e, maxE) w = let (wMinE, wE, wMaxE) = minMaxExcess0 w  in
+                                  (minE `min` (wMinE + e), e + wE, maxE `max` (wMaxE + e))
+  {-# INLINE minMaxExcess0 #-}
+
+instance MinMaxExcess0 (DVS.Vector Word16) where
+  minMaxExcess0 = DVS.foldl gen (0, 0, 0)
+    where gen :: (MinExcess, Excess, MaxExcess) -> Word16 -> (MinExcess, Excess, MaxExcess)
+          gen (minE, e, maxE) w = let (wMinE, wE, wMaxE) = minMaxExcess0 w  in
+                                  (minE `min` (wMinE + e), e + wE, maxE `max` (wMaxE + e))
+  {-# INLINE minMaxExcess0 #-}
+
+instance MinMaxExcess0 (DVS.Vector Word32) where
+  minMaxExcess0 = DVS.foldl gen (0, 0, 0)
+    where gen :: (MinExcess, Excess, MaxExcess) -> Word32 -> (MinExcess, Excess, MaxExcess)
+          gen (minE, e, maxE) w = let (wMinE, wE, wMaxE) = minMaxExcess0 w  in
+                                  (minE `min` (wMinE + e), e + wE, maxE `max` (wMaxE + e))
+  {-# INLINE minMaxExcess0 #-}
+
+instance MinMaxExcess0 (DVS.Vector Word64) where
+  minMaxExcess0 = DVS.foldl gen (0, 0, 0)
+    where gen :: (MinExcess, Excess, MaxExcess) -> Word64 -> (MinExcess, Excess, MaxExcess)
+          gen (minE, e, maxE) w = let (wMinE, wE, wMaxE) = minMaxExcess0 w  in
+                                  (minE `min` (wMinE + e), e + wE, maxE `max` (wMaxE + e))
+  {-# INLINE minMaxExcess0 #-}
+
+word8Excess0Min :: DVS.Vector Int
+word8Excess0Min =  DVS.fromList
+  [  0, -1,  0, -2,  0, -1, -1, -3,  0, -1,  0, -2,  0, -2, -2, -4
+  ,  0, -1,  0, -2,  0, -1, -1, -3,  0, -1, -1, -3, -1, -3, -3, -5
+  ,  0, -1,  0, -2,  0, -1, -1, -3,  0, -1,  0, -2,  0, -2, -2, -4
+  ,  0, -1,  0, -2,  0, -2, -2, -4,  0, -2, -2, -4, -2, -4, -4, -6
+  ,  0, -1,  0, -2,  0, -1, -1, -3,  0, -1,  0, -2,  0, -2, -2, -4
+  ,  0, -1,  0, -2,  0, -1, -1, -3,  0, -1, -1, -3, -1, -3, -3, -5
+  ,  0, -1,  0, -2,  0, -1, -1, -3,  0, -1, -1, -3, -1, -3, -3, -5
+  ,  0, -1, -1, -3, -1, -3, -3, -5, -1, -3, -3, -5, -3, -5, -5, -7
+  ,  0, -1,  0, -2,  0, -1, -1, -3,  0, -1,  0, -2,  0, -2, -2, -4
+  ,  0, -1,  0, -2,  0, -1, -1, -3,  0, -1, -1, -3, -1, -3, -3, -5
+  ,  0, -1,  0, -2,  0, -1, -1, -3,  0, -1,  0, -2,  0, -2, -2, -4
+  ,  0, -1,  0, -2,  0, -2, -2, -4,  0, -2, -2, -4, -2, -4, -4, -6
+  ,  0, -1,  0, -2,  0, -1, -1, -3,  0, -1,  0, -2,  0, -2, -2, -4
+  ,  0, -1,  0, -2,  0, -2, -2, -4,  0, -2, -2, -4, -2, -4, -4, -6
+  ,  0, -1,  0, -2,  0, -2, -2, -4,  0, -2, -2, -4, -2, -4, -4, -6
+  ,  0, -2, -2, -4, -2, -4, -4, -6, -2, -4, -4, -6, -4, -6, -6, -8
+  ]
+
+word8Excess0 :: DVS.Vector Int
+word8Excess0 =  DVS.fromList
+  [  8,  6,  6,  4,  6,  4,  4,  2,  6,  4,  4,  2,  4,  2,  2,  0
+  ,  6,  4,  4,  2,  4,  2,  2,  0,  4,  2,  2,  0,  2,  0,  0, -2
+  ,  6,  4,  4,  2,  4,  2,  2,  0,  4,  2,  2,  0,  2,  0,  0, -2
+  ,  4,  2,  2,  0,  2,  0,  0, -2,  2,  0,  0, -2,  0, -2, -2, -4
+  ,  6,  4,  4,  2,  4,  2,  2,  0,  4,  2,  2,  0,  2,  0,  0, -2
+  ,  4,  2,  2,  0,  2,  0,  0, -2,  2,  0,  0, -2,  0, -2, -2, -4
+  ,  4,  2,  2,  0,  2,  0,  0, -2,  2,  0,  0, -2,  0, -2, -2, -4
+  ,  2,  0,  0, -2,  0, -2, -2, -4,  0, -2, -2, -4, -2, -4, -4, -6
+  ,  6,  4,  4,  2,  4,  2,  2,  0,  4,  2,  2,  0,  2,  0,  0, -2
+  ,  4,  2,  2,  0,  2,  0,  0, -2,  2,  0,  0, -2,  0, -2, -2, -4
+  ,  4,  2,  2,  0,  2,  0,  0, -2,  2,  0,  0, -2,  0, -2, -2, -4
+  ,  2,  0,  0, -2,  0, -2, -2, -4,  0, -2, -2, -4, -2, -4, -4, -6
+  ,  4,  2,  2,  0,  2,  0,  0, -2,  2,  0,  0, -2,  0, -2, -2, -4
+  ,  2,  0,  0, -2,  0, -2, -2, -4,  0, -2, -2, -4, -2, -4, -4, -6
+  ,  2,  0,  0, -2,  0, -2, -2, -4,  0, -2, -2, -4, -2, -4, -4, -6
+  ,  0, -2, -2, -4, -2, -4, -4, -6, -2, -4, -4, -6, -4, -6, -6, -8
+  ]
+
+word8Excess0Max :: DVS.Vector Int
+word8Excess0Max =  DVS.fromList
+  [  8,  6,  6,  4,  6,  4,  4,  2,  6,  4,  4,  2,  4,  2,  2,  0
+  ,  6,  4,  4,  2,  4,  2,  2,  0,  4,  2,  2,  0,  2,  0,  1,  0
+  ,  6,  4,  4,  2,  4,  2,  2,  0,  4,  2,  2,  0,  2,  0,  1,  0
+  ,  4,  2,  2,  0,  2,  0,  1,  0,  3,  1,  1,  0,  2,  0,  1,  0
+  ,  6,  4,  4,  2,  4,  2,  2,  0,  4,  2,  2,  0,  2,  0,  1,  0
+  ,  4,  2,  2,  0,  2,  0,  1,  0,  3,  1,  1,  0,  2,  0,  1,  0
+  ,  5,  3,  3,  1,  3,  1,  1,  0,  3,  1,  1,  0,  2,  0,  1,  0
+  ,  4,  2,  2,  0,  2,  0,  1,  0,  3,  1,  1,  0,  2,  0,  1,  0
+  ,  7,  5,  5,  3,  5,  3,  3,  1,  5,  3,  3,  1,  3,  1,  1,  0
+  ,  5,  3,  3,  1,  3,  1,  1,  0,  3,  1,  1,  0,  2,  0,  1,  0
+  ,  5,  3,  3,  1,  3,  1,  1,  0,  3,  1,  1,  0,  2,  0,  1,  0
+  ,  4,  2,  2,  0,  2,  0,  1,  0,  3,  1,  1,  0,  2,  0,  1,  0
+  ,  6,  4,  4,  2,  4,  2,  2,  0,  4,  2,  2,  0,  2,  0,  1,  0
+  ,  4,  2,  2,  0,  2,  0,  1,  0,  3,  1,  1,  0,  2,  0,  1,  0
+  ,  5,  3,  3,  1,  3,  1,  1,  0,  3,  1,  1,  0,  2,  0,  1,  0
+  ,  4,  2,  2,  0,  2,  0,  1,  0,  3,  1,  1,  0,  2,  0,  1,  0
+  ]
diff --git a/src/HaskellWorks/Data/Excess/MinMaxExcess1.hs b/src/HaskellWorks/Data/Excess/MinMaxExcess1.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Excess/MinMaxExcess1.hs
@@ -0,0 +1,174 @@
+{-# LANGUAGE FlexibleInstances          #-}
+
+module HaskellWorks.Data.Excess.MinMaxExcess1
+  ( MinMaxExcess1(..)
+  , MaxExcess
+  , MinExcess
+  ) where
+
+import qualified Data.Vector.Storable                 as DVS
+import           Data.Word
+import           HaskellWorks.Data.Bits.BitWise
+import           HaskellWorks.Data.Bits.FixedBitSize
+import           HaskellWorks.Data.Naive
+
+type MinExcess = Int
+type MaxExcess = Int
+type Excess    = Int
+
+class MinMaxExcess1 a where
+  minMaxExcess1 :: a -> (MinExcess, Excess, MaxExcess)
+
+instance MinMaxExcess1 [Bool] where
+  minMaxExcess1 = go 0 0 0
+    where go minE maxE e (x:xs)                   = let ne = if x then e + 1 else e - 1 in
+                                                        go (minE `min` ne) (maxE `max` ne) ne xs
+          go minE maxE e _                        = (minE, e, maxE)
+  {-# INLINE minMaxExcess1 #-}
+
+instance MinMaxExcess1 (Naive Word8) where
+  minMaxExcess1 = go 0 0 0 0 . naive
+    where go minE maxE e n w | n < fixedBitSize w = let ne = if w .?. fromIntegral n then e + 1 else e - 1 in
+                                                        go (minE `min` ne) (maxE `max` ne) ne (n + 1) w
+          go minE maxE e _ _                       = (minE, e, maxE)
+  {-# INLINE minMaxExcess1 #-}
+
+instance MinMaxExcess1 (Naive Word16) where
+  minMaxExcess1 = go 0 0 0 0 . naive
+    where go minE maxE e n w | n < fixedBitSize w = let ne = if w .?. fromIntegral n then e + 1 else e - 1 in
+                                                        go (minE `min` ne) (maxE `max` ne) ne (n + 1) w
+          go minE maxE e _ _                      = (minE, e, maxE)
+  {-# INLINE minMaxExcess1 #-}
+
+instance MinMaxExcess1 (Naive Word32) where
+  minMaxExcess1 = go 0 0 0 0 . naive
+    where go minE maxE e n w | n < fixedBitSize w = let ne = if w .?. fromIntegral n then e + 1 else e - 1 in
+                                                        go (minE `min` ne) (maxE `max` ne) ne (n + 1) w
+          go minE maxE e _ _                      = (minE, e, maxE)
+  {-# INLINE minMaxExcess1 #-}
+
+instance MinMaxExcess1 (Naive Word64) where
+  minMaxExcess1 = go 0 0 0 0 . naive
+    where go minE maxE e n w | n < fixedBitSize w = let ne = if w .?. fromIntegral n then e + 1 else e - 1 in
+                                                        go (minE `min` ne) (maxE `max` ne) ne (n + 1) w
+          go minE maxE e _ _                      = (minE, e, maxE)
+  {-# INLINE minMaxExcess1 #-}
+
+instance MinMaxExcess1 Word8 where
+  minMaxExcess1 w = ( word8Excess1Min DVS.! fromIntegral w
+                    , word8Excess1    DVS.! fromIntegral w
+                    , word8Excess1Max DVS.! fromIntegral w
+                    )
+  {-# INLINE minMaxExcess1 #-}
+
+instance MinMaxExcess1 Word16 where
+  minMaxExcess1 w = ( minExcessA `min` (minExcessB + allExcessA)
+                    , allExcessA + allExcessB
+                    , maxExcessA `max` (maxExcessB + allExcessA))
+    where (minExcessA, allExcessA, maxExcessA) = minMaxExcess1 (fromIntegral  w        :: Word8)
+          (minExcessB, allExcessB, maxExcessB) = minMaxExcess1 (fromIntegral (w .>. 8) :: Word8)
+  {-# INLINE minMaxExcess1 #-}
+
+instance MinMaxExcess1 Word32 where
+  minMaxExcess1 w = ( minExcessA `min` (minExcessB + allExcessA)
+                    , allExcessA + allExcessB
+                    , maxExcessA `max` (maxExcessB + allExcessA))
+    where (minExcessA, allExcessA, maxExcessA) = minMaxExcess1 (fromIntegral  w         :: Word16)
+          (minExcessB, allExcessB, maxExcessB) = minMaxExcess1 (fromIntegral (w .>. 16) :: Word16)
+  {-# INLINE minMaxExcess1 #-}
+
+instance MinMaxExcess1 Word64 where
+  minMaxExcess1 w = ( minExcessA `min` (minExcessB + allExcessA)
+                    , allExcessA + allExcessB
+                    , maxExcessA `max` (maxExcessB + allExcessA))
+    where (minExcessA, allExcessA, maxExcessA) = minMaxExcess1 (fromIntegral  w         :: Word32)
+          (minExcessB, allExcessB, maxExcessB) = minMaxExcess1 (fromIntegral (w .>. 32) :: Word32)
+  {-# INLINE minMaxExcess1 #-}
+
+instance MinMaxExcess1 (DVS.Vector Word8) where
+  minMaxExcess1 = DVS.foldl gen (0, 0, 0)
+    where gen :: (MinExcess, Excess, MaxExcess) -> Word8 -> (MinExcess, Excess, MaxExcess)
+          gen (minE, e, maxE) w = let (wMinE, wE, wMaxE) = minMaxExcess1 w  in
+                                  (minE `min` (wMinE + e), e + wE, maxE `max` (wMaxE + e))
+  {-# INLINE minMaxExcess1 #-}
+
+instance MinMaxExcess1 (DVS.Vector Word16) where
+  minMaxExcess1 = DVS.foldl gen (0, 0, 0)
+    where gen :: (MinExcess, Excess, MaxExcess) -> Word16 -> (MinExcess, Excess, MaxExcess)
+          gen (minE, e, maxE) w = let (wMinE, wE, wMaxE) = minMaxExcess1 w  in
+                                  (minE `min` (wMinE + e), e + wE, maxE `max` (wMaxE + e))
+  {-# INLINE minMaxExcess1 #-}
+
+instance MinMaxExcess1 (DVS.Vector Word32) where
+  minMaxExcess1 = DVS.foldl gen (0, 0, 0)
+    where gen :: (MinExcess, Excess, MaxExcess) -> Word32 -> (MinExcess, Excess, MaxExcess)
+          gen (minE, e, maxE) w = let (wMinE, wE, wMaxE) = minMaxExcess1 w  in
+                                  (minE `min` (wMinE + e), e + wE, maxE `max` (wMaxE + e))
+  {-# INLINE minMaxExcess1 #-}
+
+instance MinMaxExcess1 (DVS.Vector Word64) where
+  minMaxExcess1 = DVS.foldl gen (0, 0, 0)
+    where gen :: (MinExcess, Excess, MaxExcess) -> Word64 -> (MinExcess, Excess, MaxExcess)
+          gen (minE, e, maxE) w = let (wMinE, wE, wMaxE) = minMaxExcess1 w  in
+                                  (minE `min` (wMinE + e), e + wE, maxE `max` (wMaxE + e))
+  {-# INLINE minMaxExcess1 #-}
+
+word8Excess1Min :: DVS.Vector Int
+word8Excess1Min =  DVS.fromList
+  [ -8, -6, -6, -4, -6, -4, -4, -2, -6, -4, -4, -2, -4, -2, -2,  0
+  , -6, -4, -4, -2, -4, -2, -2,  0, -4, -2, -2,  0, -2,  0, -1,  0
+  , -6, -4, -4, -2, -4, -2, -2,  0, -4, -2, -2,  0, -2,  0, -1,  0
+  , -4, -2, -2,  0, -2,  0, -1,  0, -3, -1, -1,  0, -2,  0, -1,  0
+  , -6, -4, -4, -2, -4, -2, -2,  0, -4, -2, -2,  0, -2,  0, -1,  0
+  , -4, -2, -2,  0, -2,  0, -1,  0, -3, -1, -1,  0, -2,  0, -1,  0
+  , -5, -3, -3, -1, -3, -1, -1,  0, -3, -1, -1,  0, -2,  0, -1,  0
+  , -4, -2, -2,  0, -2,  0, -1,  0, -3, -1, -1,  0, -2,  0, -1,  0
+  , -7, -5, -5, -3, -5, -3, -3, -1, -5, -3, -3, -1, -3, -1, -1,  0
+  , -5, -3, -3, -1, -3, -1, -1,  0, -3, -1, -1,  0, -2,  0, -1,  0
+  , -5, -3, -3, -1, -3, -1, -1,  0, -3, -1, -1,  0, -2,  0, -1,  0
+  , -4, -2, -2,  0, -2,  0, -1,  0, -3, -1, -1,  0, -2,  0, -1,  0
+  , -6, -4, -4, -2, -4, -2, -2,  0, -4, -2, -2,  0, -2,  0, -1,  0
+  , -4, -2, -2,  0, -2,  0, -1,  0, -3, -1, -1,  0, -2,  0, -1,  0
+  , -5, -3, -3, -1, -3, -1, -1,  0, -3, -1, -1,  0, -2,  0, -1,  0
+  , -4, -2, -2,  0, -2,  0, -1,  0, -3, -1, -1,  0, -2,  0, -1,  0
+  ]
+
+word8Excess1 :: DVS.Vector Int
+word8Excess1 =  DVS.fromList
+  [ -8, -6, -6, -4, -6, -4, -4, -2, -6, -4, -4, -2, -4, -2, -2,  0
+  , -6, -4, -4, -2, -4, -2, -2,  0, -4, -2, -2,  0, -2,  0,  0,  2
+  , -6, -4, -4, -2, -4, -2, -2,  0, -4, -2, -2,  0, -2,  0,  0,  2
+  , -4, -2, -2,  0, -2,  0,  0,  2, -2,  0,  0,  2,  0,  2,  2,  4
+  , -6, -4, -4, -2, -4, -2, -2,  0, -4, -2, -2,  0, -2,  0,  0,  2
+  , -4, -2, -2,  0, -2,  0,  0,  2, -2,  0,  0,  2,  0,  2,  2,  4
+  , -4, -2, -2,  0, -2,  0,  0,  2, -2,  0,  0,  2,  0,  2,  2,  4
+  , -2,  0,  0,  2,  0,  2,  2,  4,  0,  2,  2,  4,  2,  4,  4,  6
+  , -6, -4, -4, -2, -4, -2, -2,  0, -4, -2, -2,  0, -2,  0,  0,  2
+  , -4, -2, -2,  0, -2,  0,  0,  2, -2,  0,  0,  2,  0,  2,  2,  4
+  , -4, -2, -2,  0, -2,  0,  0,  2, -2,  0,  0,  2,  0,  2,  2,  4
+  , -2,  0,  0,  2,  0,  2,  2,  4,  0,  2,  2,  4,  2,  4,  4,  6
+  , -4, -2, -2,  0, -2,  0,  0,  2, -2,  0,  0,  2,  0,  2,  2,  4
+  , -2,  0,  0,  2,  0,  2,  2,  4,  0,  2,  2,  4,  2,  4,  4,  6
+  , -2,  0,  0,  2,  0,  2,  2,  4,  0,  2,  2,  4,  2,  4,  4,  6
+  ,  0,  2,  2,  4,  2,  4,  4,  6,  2,  4,  4,  6,  4,  6,  6,  8
+  ]
+
+word8Excess1Max :: DVS.Vector Int
+word8Excess1Max =  DVS.fromList
+  [  0,  1,  0,  2,  0,  1,  1,  3,  0,  1,  0,  2,  0,  2,  2,  4
+  ,  0,  1,  0,  2,  0,  1,  1,  3,  0,  1,  1,  3,  1,  3,  3,  5
+  ,  0,  1,  0,  2,  0,  1,  1,  3,  0,  1,  0,  2,  0,  2,  2,  4
+  ,  0,  1,  0,  2,  0,  2,  2,  4,  0,  2,  2,  4,  2,  4,  4,  6
+  ,  0,  1,  0,  2,  0,  1,  1,  3,  0,  1,  0,  2,  0,  2,  2,  4
+  ,  0,  1,  0,  2,  0,  1,  1,  3,  0,  1,  1,  3,  1,  3,  3,  5
+  ,  0,  1,  0,  2,  0,  1,  1,  3,  0,  1,  1,  3,  1,  3,  3,  5
+  ,  0,  1,  1,  3,  1,  3,  3,  5,  1,  3,  3,  5,  3,  5,  5,  7
+  ,  0,  1,  0,  2,  0,  1,  1,  3,  0,  1,  0,  2,  0,  2,  2,  4
+  ,  0,  1,  0,  2,  0,  1,  1,  3,  0,  1,  1,  3,  1,  3,  3,  5
+  ,  0,  1,  0,  2,  0,  1,  1,  3,  0,  1,  0,  2,  0,  2,  2,  4
+  ,  0,  1,  0,  2,  0,  2,  2,  4,  0,  2,  2,  4,  2,  4,  4,  6
+  ,  0,  1,  0,  2,  0,  1,  1,  3,  0,  1,  0,  2,  0,  2,  2,  4
+  ,  0,  1,  0,  2,  0,  2,  2,  4,  0,  2,  2,  4,  2,  4,  4,  6
+  ,  0,  1,  0,  2,  0,  2,  2,  4,  0,  2,  2,  4,  2,  4,  4,  6
+  ,  0,  2,  2,  4,  2,  4,  4,  6,  2,  4,  4,  6,  4,  6,  6,  8
+  ]
diff --git a/test/HaskellWorks/Data/Excess/MinMaxExcess0Spec.hs b/test/HaskellWorks/Data/Excess/MinMaxExcess0Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/HaskellWorks/Data/Excess/MinMaxExcess0Spec.hs
@@ -0,0 +1,149 @@
+{-# OPTIONS_GHC -fno-warn-incomplete-patterns #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module HaskellWorks.Data.Excess.MinMaxExcess0Spec (spec) where
+
+import qualified Data.Vector.Storable                             as DVS
+import           Data.Word
+import           HaskellWorks.Data.Bits.Word
+import           HaskellWorks.Data.Naive
+import           HaskellWorks.Data.Excess.MinMaxExcess0
+import           Test.Hspec
+import           Test.QuickCheck
+
+{-# ANN module ("HLint: Ignore Redundant do" :: String) #-}
+{-# ANN module ("HLint: Ignore Reduce duplication"  :: String) #-}
+
+spec :: Spec
+spec = describe "HaskellWorks.Data.Excess.MinMaxExcess0Spec" $ do
+  describe "For Word8" $ do
+    it "Excess should be between min excess and max excess" $
+      property $ \(w :: Word8) ->
+        let (minE, e, maxE) = minMaxExcess0 w in
+        minE <= e && e <= maxE
+    it "minE2 == minE0 `min` (minE1 + e0)" $
+      property $ \(w0 :: Word8, w1 :: Word8) ->
+        let w2 = leConcat w0 w1 in
+        let (minE0, e0, _) = minMaxExcess0 w0 in
+        let (minE1, _ , _) = minMaxExcess0 w1 in
+        let (minE2, _ , _) = minMaxExcess0 w2 in
+        minE2 == minE0 `min` (minE1 + e0)
+    it "maxE2 == maxE0 `max` (maxE1 + e0)" $
+      property $ \(w0 :: Word8, w1 :: Word8) ->
+        let w2 = leConcat w0 w1 in
+        let (_, e0, maxE0) = minMaxExcess0 w0 in
+        let (_, _ , maxE1) = minMaxExcess0 w1 in
+        let (_, _ , maxE2) = minMaxExcess0 w2 in
+        maxE2 == maxE0 `max` (maxE1 + e0)
+    it "minE2 == minE0 `min` (minE1 + e0) via vector" $
+      property $ \(w0 :: Word8, w1 :: Word8) ->
+        let w2 = DVS.fromList [w0, w1] in
+        let (minE0, e0, _) = minMaxExcess0 w0 in
+        let (minE1, _ , _) = minMaxExcess0 w1 in
+        let (minE2, _ , _) = minMaxExcess0 w2 in
+        minE2 == minE0 `min` (minE1 + e0)
+    it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $
+      property $ \(w0 :: Word8, w1 :: Word8) ->
+        let w2 = DVS.fromList [w0, w1] in
+        let (_, e0, maxE0) = minMaxExcess0 w0 in
+        let (_, _ , maxE1) = minMaxExcess0 w1 in
+        let (_, _ , maxE2) = minMaxExcess0 w2 in
+        maxE2 == maxE0 `max` (maxE1 + e0)
+  describe "For Word16" $ do
+    it "Excess should be between min excess and max excess" $
+      property $ \(w :: Word16) ->
+        let (minE, e, maxE) = minMaxExcess0 w in
+        minE <= e && e <= maxE
+    it "minE2 == minE0 `min` (minE1 + e0)" $
+      property $ \(w0 :: Word16, w1 :: Word16) ->
+        let w2 = leConcat w0 w1 in
+        let (minE0, e0, _) = minMaxExcess0 w0 in
+        let (minE1, _ , _) = minMaxExcess0 w1 in
+        let (minE2, _ , _) = minMaxExcess0 w2 in
+        minE2 == minE0 `min` (minE1 + e0)
+    it "maxE2 == maxE0 `max` (maxE1 + e0)" $
+      property $ \(w0 :: Word16, w1 :: Word16) ->
+        let w2 = leConcat w0 w1 in
+        let (_, e0, maxE0) = minMaxExcess0 w0 in
+        let (_, _ , maxE1) = minMaxExcess0 w1 in
+        let (_, _ , maxE2) = minMaxExcess0 w2 in
+        maxE2 == maxE0 `max` (maxE1 + e0)
+    it "minE2 == minE0 `min` (minE1 + e0) via vector" $
+      property $ \(w0 :: Word16, w1 :: Word16) ->
+        let w2 = DVS.fromList [w0, w1] in
+        let (minE0, e0, _) = minMaxExcess0 w0 in
+        let (minE1, _ , _) = minMaxExcess0 w1 in
+        let (minE2, _ , _) = minMaxExcess0 w2 in
+        minE2 == minE0 `min` (minE1 + e0)
+    it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $
+      property $ \(w0 :: Word16, w1 :: Word16) ->
+        let w2 = DVS.fromList [w0, w1] in
+        let (_, e0, maxE0) = minMaxExcess0 w0 in
+        let (_, _ , maxE1) = minMaxExcess0 w1 in
+        let (_, _ , maxE2) = minMaxExcess0 w2 in
+        maxE2 == maxE0 `max` (maxE1 + e0)
+    describe "For Word32" $ do
+      it "Excess should be between min excess and max excess" $
+        property $ \(w :: Word32) ->
+          let (minE, e, maxE) = minMaxExcess0 w in
+          minE <= e && e <= maxE
+      it "minE2 == minE0 `min` (minE1 + e0)" $
+        property $ \(w0 :: Word32, w1 :: Word32) ->
+          let w2 = leConcat w0 w1 in
+          let (minE0, e0, _) = minMaxExcess0 w0 in
+          let (minE1, _ , _) = minMaxExcess0 w1 in
+          let (minE2, _ , _) = minMaxExcess0 w2 in
+          minE2 == minE0 `min` (minE1 + e0)
+      it "maxE2 == maxE0 `max` (maxE1 + e0)" $
+        property $ \(w0 :: Word32, w1 :: Word32) ->
+          let w2 = leConcat w0 w1 in
+          let (_, e0, maxE0) = minMaxExcess0 w0 in
+          let (_, _ , maxE1) = minMaxExcess0 w1 in
+          let (_, _ , maxE2) = minMaxExcess0 w2 in
+          maxE2 == maxE0 `max` (maxE1 + e0)
+      it "minE2 == minE0 `min` (minE1 + e0) via vector" $
+        property $ \(w0 :: Word32, w1 :: Word32) ->
+          let w2 = DVS.fromList [w0, w1] in
+          let (minE0, e0, _) = minMaxExcess0 w0 in
+          let (minE1, _ , _) = minMaxExcess0 w1 in
+          let (minE2, _ , _) = minMaxExcess0 w2 in
+          minE2 == minE0 `min` (minE1 + e0)
+      it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $
+        property $ \(w0 :: Word32, w1 :: Word32) ->
+          let w2 = DVS.fromList [w0, w1] in
+          let (_, e0, maxE0) = minMaxExcess0 w0 in
+          let (_, _ , maxE1) = minMaxExcess0 w1 in
+          let (_, _ , maxE2) = minMaxExcess0 w2 in
+          maxE2 == maxE0 `max` (maxE1 + e0)
+  describe "For Word64" $ do
+    it "Excess should be between min excess and max excess" $
+      property $ \(w :: Word64) ->
+        let (minE, e, maxE) = minMaxExcess0 w in
+        minE <= e && e <= maxE
+    it "minE2 == minE0 `min` (minE1 + e0) via vector" $
+      property $ \(w0 :: Word64, w1 :: Word64) ->
+        let w2 = DVS.fromList [w0, w1] in
+        let (minE0, e0, _) = minMaxExcess0 w0 in
+        let (minE1, _ , _) = minMaxExcess0 w1 in
+        let (minE2, _ , _) = minMaxExcess0 w2 in
+        minE2 == minE0 `min` (minE1 + e0)
+    it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $
+      property $ \(w0 :: Word64, w1 :: Word64) ->
+        let w2 = DVS.fromList [w0, w1] in
+        let (_, e0, maxE0) = minMaxExcess0 w0 in
+        let (_, _ , maxE1) = minMaxExcess0 w1 in
+        let (_, _ , maxE2) = minMaxExcess0 w2 in
+        maxE2 == maxE0 `max` (maxE1 + e0)
+    describe "Equivalent to native implementation" $ do
+      it "For Word8" $ do
+        property $ \(w :: Word8) ->
+          minMaxExcess0 w == minMaxExcess0 (Naive w)
+      it "For Word16" $ do
+        property $ \(w :: Word16) ->
+          minMaxExcess0 w == minMaxExcess0 (Naive w)
+      it "For Word32" $ do
+        property $ \(w :: Word32) ->
+          minMaxExcess0 w == minMaxExcess0 (Naive w)
+      it "For Word64" $ do
+        property $ \(w :: Word64) ->
+          minMaxExcess0 w == minMaxExcess0 (Naive w)
diff --git a/test/HaskellWorks/Data/Excess/MinMaxExcess1Spec.hs b/test/HaskellWorks/Data/Excess/MinMaxExcess1Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/HaskellWorks/Data/Excess/MinMaxExcess1Spec.hs
@@ -0,0 +1,149 @@
+{-# OPTIONS_GHC -fno-warn-incomplete-patterns #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module HaskellWorks.Data.Excess.MinMaxExcess1Spec (spec) where
+
+import qualified Data.Vector.Storable                             as DVS
+import           Data.Word
+import           HaskellWorks.Data.Bits.Word
+import           HaskellWorks.Data.Excess.MinMaxExcess1
+import           HaskellWorks.Data.Naive
+import           Test.Hspec
+import           Test.QuickCheck
+
+{-# ANN module ("HLint: Ignore Redundant do" :: String) #-}
+{-# ANN module ("HLint: Ignore Reduce duplication"  :: String) #-}
+
+spec :: Spec
+spec = describe "HaskellWorks.Data.Excess.MinMaxExcess1Spec" $ do
+  describe "For Word8" $ do
+    it "Excess should be between min excess and max excess" $
+      property $ \(w :: Word8) ->
+        let (minE, e, maxE) = minMaxExcess1 w in
+        minE <= e && e <= maxE
+    it "minE2 == minE0 `min` (minE1 + e0)" $
+      property $ \(w0 :: Word8, w1 :: Word8) ->
+        let w2 = leConcat w0 w1 in
+        let (minE0, e0, _) = minMaxExcess1 w0 in
+        let (minE1, _ , _) = minMaxExcess1 w1 in
+        let (minE2, _ , _) = minMaxExcess1 w2 in
+        minE2 == minE0 `min` (minE1 + e0)
+    it "maxE2 == maxE0 `max` (maxE1 + e0)" $
+      property $ \(w0 :: Word8, w1 :: Word8) ->
+        let w2 = leConcat w0 w1 in
+        let (_, e0, maxE0) = minMaxExcess1 w0 in
+        let (_, _ , maxE1) = minMaxExcess1 w1 in
+        let (_, _ , maxE2) = minMaxExcess1 w2 in
+        maxE2 == maxE0 `max` (maxE1 + e0)
+    it "minE2 == minE0 `min` (minE1 + e0) via vector" $
+      property $ \(w0 :: Word8, w1 :: Word8) ->
+        let w2 = DVS.fromList [w0, w1] in
+        let (minE0, e0, _) = minMaxExcess1 w0 in
+        let (minE1, _ , _) = minMaxExcess1 w1 in
+        let (minE2, _ , _) = minMaxExcess1 w2 in
+        minE2 == minE0 `min` (minE1 + e0)
+    it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $
+      property $ \(w0 :: Word8, w1 :: Word8) ->
+        let w2 = DVS.fromList [w0, w1] in
+        let (_, e0, maxE0) = minMaxExcess1 w0 in
+        let (_, _ , maxE1) = minMaxExcess1 w1 in
+        let (_, _ , maxE2) = minMaxExcess1 w2 in
+        maxE2 == maxE0 `max` (maxE1 + e0)
+  describe "For Word16" $ do
+    it "Excess should be between min excess and max excess" $
+      property $ \(w :: Word16) ->
+        let (minE, e, maxE) = minMaxExcess1 w in
+        minE <= e && e <= maxE
+    it "minE2 == minE0 `min` (minE1 + e0)" $
+      property $ \(w0 :: Word16, w1 :: Word16) ->
+        let w2 = leConcat w0 w1 in
+        let (minE0, e0, _) = minMaxExcess1 w0 in
+        let (minE1, _ , _) = minMaxExcess1 w1 in
+        let (minE2, _ , _) = minMaxExcess1 w2 in
+        minE2 == minE0 `min` (minE1 + e0)
+    it "maxE2 == maxE0 `max` (maxE1 + e0)" $
+      property $ \(w0 :: Word16, w1 :: Word16) ->
+        let w2 = leConcat w0 w1 in
+        let (_, e0, maxE0) = minMaxExcess1 w0 in
+        let (_, _ , maxE1) = minMaxExcess1 w1 in
+        let (_, _ , maxE2) = minMaxExcess1 w2 in
+        maxE2 == maxE0 `max` (maxE1 + e0)
+    it "minE2 == minE0 `min` (minE1 + e0) via vector" $
+      property $ \(w0 :: Word16, w1 :: Word16) ->
+        let w2 = DVS.fromList [w0, w1] in
+        let (minE0, e0, _) = minMaxExcess1 w0 in
+        let (minE1, _ , _) = minMaxExcess1 w1 in
+        let (minE2, _ , _) = minMaxExcess1 w2 in
+        minE2 == minE0 `min` (minE1 + e0)
+    it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $
+      property $ \(w0 :: Word16, w1 :: Word16) ->
+        let w2 = DVS.fromList [w0, w1] in
+        let (_, e0, maxE0) = minMaxExcess1 w0 in
+        let (_, _ , maxE1) = minMaxExcess1 w1 in
+        let (_, _ , maxE2) = minMaxExcess1 w2 in
+        maxE2 == maxE0 `max` (maxE1 + e0)
+    describe "For Word32" $ do
+      it "Excess should be between min excess and max excess" $
+        property $ \(w :: Word32) ->
+          let (minE, e, maxE) = minMaxExcess1 w in
+          minE <= e && e <= maxE
+      it "minE2 == minE0 `min` (minE1 + e0)" $
+        property $ \(w0 :: Word32, w1 :: Word32) ->
+          let w2 = leConcat w0 w1 in
+          let (minE0, e0, _) = minMaxExcess1 w0 in
+          let (minE1, _ , _) = minMaxExcess1 w1 in
+          let (minE2, _ , _) = minMaxExcess1 w2 in
+          minE2 == minE0 `min` (minE1 + e0)
+      it "maxE2 == maxE0 `max` (maxE1 + e0)" $
+        property $ \(w0 :: Word32, w1 :: Word32) ->
+          let w2 = leConcat w0 w1 in
+          let (_, e0, maxE0) = minMaxExcess1 w0 in
+          let (_, _ , maxE1) = minMaxExcess1 w1 in
+          let (_, _ , maxE2) = minMaxExcess1 w2 in
+          maxE2 == maxE0 `max` (maxE1 + e0)
+      it "minE2 == minE0 `min` (minE1 + e0) via vector" $
+        property $ \(w0 :: Word32, w1 :: Word32) ->
+          let w2 = DVS.fromList [w0, w1] in
+          let (minE0, e0, _) = minMaxExcess1 w0 in
+          let (minE1, _ , _) = minMaxExcess1 w1 in
+          let (minE2, _ , _) = minMaxExcess1 w2 in
+          minE2 == minE0 `min` (minE1 + e0)
+      it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $
+        property $ \(w0 :: Word32, w1 :: Word32) ->
+          let w2 = DVS.fromList [w0, w1] in
+          let (_, e0, maxE0) = minMaxExcess1 w0 in
+          let (_, _ , maxE1) = minMaxExcess1 w1 in
+          let (_, _ , maxE2) = minMaxExcess1 w2 in
+          maxE2 == maxE0 `max` (maxE1 + e0)
+  describe "For Word64" $ do
+    it "Excess should be between min excess and max excess" $
+      property $ \(w :: Word64) ->
+        let (minE, e, maxE) = minMaxExcess1 w in
+        minE <= e && e <= maxE
+    it "minE2 == minE0 `min` (minE1 + e0) via vector" $
+      property $ \(w0 :: Word64, w1 :: Word64) ->
+        let w2 = DVS.fromList [w0, w1] in
+        let (minE0, e0, _) = minMaxExcess1 w0 in
+        let (minE1, _ , _) = minMaxExcess1 w1 in
+        let (minE2, _ , _) = minMaxExcess1 w2 in
+        minE2 == minE0 `min` (minE1 + e0)
+    it "maxE2 == maxE0 `max` (maxE1 + e0) via vector" $
+      property $ \(w0 :: Word64, w1 :: Word64) ->
+        let w2 = DVS.fromList [w0, w1] in
+        let (_, e0, maxE0) = minMaxExcess1 w0 in
+        let (_, _ , maxE1) = minMaxExcess1 w1 in
+        let (_, _ , maxE2) = minMaxExcess1 w2 in
+        maxE2 == maxE0 `max` (maxE1 + e0)
+  describe "Equivalent to native implementation" $ do
+    it "For Word8" $ do
+      property $ \(w :: Word8) ->
+        minMaxExcess1 w == minMaxExcess1 (Naive w)
+    it "For Word16" $ do
+      property $ \(w :: Word16) ->
+        minMaxExcess1 w == minMaxExcess1 (Naive w)
+    it "For Word32" $ do
+      property $ \(w :: Word32) ->
+        minMaxExcess1 w == minMaxExcess1 (Naive w)
+    it "For Word64" $ do
+      property $ \(w :: Word64) ->
+        minMaxExcess1 w == minMaxExcess1 (Naive w)
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,1 @@
+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
