diff --git a/Changelog.md b/Changelog.md
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,7 +1,12 @@
+# 0.0.4
+- Add `bitmaskWithRejection32'` and `bitmaskWithRejection64'`
+  which generate numbers in closed range `[0, n]`.
+  Unticked variants generate in closed-open range `[0, n)`.
+
 # 0.0.3
 
 - Add `System.Random.SplitMix32` module
-- Add `bitmaskWithRejection32` and `bitmaskWithRejection64` module
+- Add `bitmaskWithRejection32` and `bitmaskWithRejection64` functions
 - Add `nextWord32`, `nextTwoWord32` and `nextFloat`
 - Add `random` flag, dropping dependency on `random`
   (breaks things, e.g. `QuickCheck`, when disabled).
diff --git a/splitmix.cabal b/splitmix.cabal
--- a/splitmix.cabal
+++ b/splitmix.cabal
@@ -1,6 +1,6 @@
 cabal-version:      >=1.10
 name:               splitmix
-version:            0.0.3
+version:            0.0.4
 synopsis:           Fast Splittable PRNG
 description:
   Pure Haskell implementation of SplitMix described in
@@ -33,7 +33,19 @@
 category:           System, Random
 build-type:         Simple
 tested-with:
-  GHC ==8.8.1 || ==8.6.5 || ==8.4.4 || ==8.2.2 || ==8.0.2 || ==7.10.3 || ==7.8.4 || ==7.6.3 || ==7.4.2 || ==7.2.2 || ==7.0.4
+    GHC ==7.0.4
+     || ==7.2.2
+     || ==7.4.2
+     || ==7.6.3
+     || ==7.8.4
+     || ==7.10.3
+     || ==8.0.2
+     || ==8.2.2
+     || ==8.4.4
+     || ==8.6.5
+     || ==8.8.2
+     || ==8.10.1
+  , GHCJS ==8.4
 
 extra-source-files:
   README.md
@@ -63,7 +75,7 @@
   -- ghc-options: -fplugin=DumpCore -fplugin-opt DumpCore:core-html
 
   build-depends:
-      base     >=4.3     && <4.14
+      base     >=4.3     && <4.15
     , deepseq  >=1.3.0.0 && <1.5
     , time     >=1.2.0.3 && <1.10
 
diff --git a/src/System/Random/SplitMix.hs b/src/System/Random/SplitMix.hs
--- a/src/System/Random/SplitMix.hs
+++ b/src/System/Random/SplitMix.hs
@@ -26,9 +26,9 @@
 --  but GHC-7.0 and GHC-7.2 have slow implementation, as there
 --  are no native 'popCount'.
 --
-{-# LANGUAGE CPP          #-}
+{-# LANGUAGE CPP         #-}
 #if __GLASGOW_HASKELL__ >= 702
-{-# LANGUAGE Trustworthy  #-}
+{-# LANGUAGE Trustworthy #-}
 #endif
 module System.Random.SplitMix (
     SMGen,
@@ -41,7 +41,9 @@
     splitSMGen,
     -- * Generation
     bitmaskWithRejection32,
+    bitmaskWithRejection32',
     bitmaskWithRejection64,
+    bitmaskWithRejection64',
     -- * Initialisation
     mkSMGen,
     initSMGen,
@@ -245,6 +247,36 @@
     go g = let (x, g') = nextWord64 g
                x' = x .&. mask
            in if x' >= range
+              then go g'
+              else (x', g')
+
+-- | /Bitmask with rejection/ method of generating subrange of 'Word32'.
+--
+-- @since 0.0.4
+bitmaskWithRejection32' :: Word32 -> SMGen -> (Word32, SMGen)
+bitmaskWithRejection32' range = go where
+    mask = complement zeroBits `shiftR` countLeadingZeros (range .|. 1)
+    go g = let (x, g') = nextWord32 g
+               x' = x .&. mask
+           in if x' > range
+              then go g'
+              else (x', g')
+
+-- | /Bitmask with rejection/ method of generating subrange of 'Word64'.
+--
+-- @bitmaskWithRejection64' w64@ generates random numbers in closed-closed
+-- range of @[0, w64]@.
+--
+-- >>> take 20 $ unfoldr (Just . bitmaskWithRejection64' 5) (mkSMGen 1337)
+-- [3,1,4,1,2,3,1,1,0,3,4,5,2,3,0,2,3,5,3,4]
+--
+-- @since 0.0.4
+bitmaskWithRejection64' :: Word64 -> SMGen -> (Word64, SMGen)
+bitmaskWithRejection64' range = go where
+    mask = complement zeroBits `shiftR` countLeadingZeros (range .|. 1)
+    go g = let (x, g') = nextWord64 g
+               x' = x .&. mask
+           in if x' > range
               then go g'
               else (x', g')
 
diff --git a/src/System/Random/SplitMix32.hs b/src/System/Random/SplitMix32.hs
--- a/src/System/Random/SplitMix32.hs
+++ b/src/System/Random/SplitMix32.hs
@@ -9,9 +9,9 @@
 --  but GHC-7.0 and GHC-7.2 have slow implementation, as there
 --  are no native 'popCount'.
 --
-{-# LANGUAGE CPP          #-}
+{-# LANGUAGE CPP         #-}
 #if __GLASGOW_HASKELL__ >= 702
-{-# LANGUAGE Trustworthy  #-}
+{-# LANGUAGE Trustworthy #-}
 #endif
 module System.Random.SplitMix32 (
     SMGen,
@@ -24,7 +24,9 @@
     splitSMGen,
     -- * Generation
     bitmaskWithRejection32,
+    bitmaskWithRejection32',
     bitmaskWithRejection64,
+    bitmaskWithRejection64',
     -- * Initialisation
     mkSMGen,
     initSMGen,
@@ -242,6 +244,36 @@
     go g = let (x, g') = nextWord64 g
                x' = x .&. mask
            in if x' >= range
+              then go g'
+              else (x', g')
+
+-- | /Bitmask with rejection/ method of generating subrange of 'Word32'.
+--
+-- @since 0.0.4
+bitmaskWithRejection32' :: Word32 -> SMGen -> (Word32, SMGen)
+bitmaskWithRejection32' range = go where
+    mask = complement zeroBits `shiftR` countLeadingZeros (range .|. 1)
+    go g = let (x, g') = nextWord32 g
+               x' = x .&. mask
+           in if x' > range
+              then go g'
+              else (x', g')
+
+-- | /Bitmask with rejection/ method of generating subrange of 'Word64'.
+--
+-- @bitmaskWithRejection64' w64@ generates random numbers in closed-closed
+-- range of @[0, w64]@.
+--
+-- >>> take 20 $ unfoldr (Just . bitmaskWithRejection64' 5) (mkSMGen 1337)
+-- [0,2,4,2,1,4,2,4,5,5,2,2,5,3,5,0,3,2,2,2]
+--
+-- @since 0.0.4
+bitmaskWithRejection64' :: Word64 -> SMGen -> (Word64, SMGen)
+bitmaskWithRejection64' range = go where
+    mask = complement zeroBits `shiftR` countLeadingZeros (range .|. 1)
+    go g = let (x, g') = nextWord64 g
+               x' = x .&. mask
+           in if x' > range
               then go g'
               else (x', g')
 
