diff --git a/exact-real.cabal b/exact-real.cabal
--- a/exact-real.cabal
+++ b/exact-real.cabal
@@ -1,5 +1,5 @@
 name:         exact-real
-version:      0.11.3
+version:      0.12.0
 synopsis:     Exact real arithmetic
 description:
   A type to represent exact real numbers using fast binary Cauchy sequences.
@@ -31,7 +31,8 @@
   build-depends:
     base        >= 4.8 && < 4.9,
     integer-gmp           < 1.1.0.0,
-    memoize     >= 0.7 && < 0.8
+    memoize     >= 0.7 && < 0.8,
+    random      >= 1.0 && < 1.2
   hs-source-dirs:
     src
   default-language:
@@ -75,6 +76,7 @@
     Fractional,
     Num,
     Ord,
+    Random,
     Read,
     Real,
     RealFloat,
@@ -90,8 +92,8 @@
     tasty-quickcheck >= 0.8  && < 0.9,
     tasty-hunit      >= 0.9  && < 0.10,
     QuickCheck       >= 2.8  && < 2.9,
-    checkers         >= 0.4  && < 0.5,
     random           >= 1.0  && < 1.2,
+    checkers         >= 0.4  && < 0.5,
     exact-real
 
 test-suite doctest
diff --git a/src/Data/CReal/Internal.hs b/src/Data/CReal/Internal.hs
--- a/src/Data/CReal/Internal.hs
+++ b/src/Data/CReal/Internal.hs
@@ -3,6 +3,7 @@
 {-# LANGUAGE MagicHash #-}
 {-# LANGUAGE MultiWayIf #-}
 {-# LANGUAGE PostfixOperators #-}
+{-# LANGUAGE ScopedTypeVariables #-}
 
 -----------------------------------------------------------------------------
 -- | This module exports a bunch of utilities for working inside the CReal
@@ -64,6 +65,7 @@
 import GHC.TypeLits
 import Numeric (readSigned, readFloat)
 import Data.Function.Memoize (memoize)
+import System.Random (Random(..))
 
 {-# ANN module "HLint: ignore Reduce duplication" #-}
 
@@ -302,6 +304,20 @@
                 in compare ((x - y) `atPrecision` p) 0
   max (CR x) (CR y) = crMemoize (\p -> max (x p) (y p))
   min (CR x) (CR y) = crMemoize (\p -> min (x p) (y p))
+
+-- | The 'Random' instance for @\'CReal\' p@ will return random number with at
+-- least @p@ digits of precision, every digit after that is zero.
+instance KnownNat n => Random (CReal n) where
+  randomR (lo, hi) g = let d = hi - lo
+                           l = 1 + log2 (abs d `atPrecision` 0)
+                           p = l + crealPrecision lo
+                           (n, g') = randomR (0, 2^p) g
+                           r = fromRational (n % 2^p)
+                       in (r * d + lo, g')
+  random g = let p = 1 + crealPrecision (undefined :: CReal n)
+                 (n, g') = randomR (0, max 0 (2^p - 2)) g
+                 r = fromRational (n % 2^p)
+             in (r, g')
 
 --------------------------------------------------------------------------------
 -- Some utility functions
diff --git a/test/Data/CReal/Extra.hs b/test/Data/CReal/Extra.hs
--- a/test/Data/CReal/Extra.hs
+++ b/test/Data/CReal/Extra.hs
@@ -5,10 +5,7 @@
   ) where
 
 import Data.CReal
-import Data.CReal.Internal (log2)
-import Data.Ratio ((%))
 import GHC.TypeLits
-import System.Random (Random(..))
 import Test.QuickCheck (Arbitrary(..), choose)
 import Test.QuickCheck.Checkers (EqProp(..), eq)
 
@@ -20,13 +17,4 @@
     integralPart <- fromInteger <$> arbitrary
     fractionalPart <- choose (-0.5, 0.5)
     pure (integralPart + fractionalPart)
-
-instance KnownNat n => Random (CReal n) where
-  randomR (lo, hi) g = let d = hi - lo
-                           l = 1 + log2 (abs d `atPrecision` 0)
-                           p = l + crealPrecision lo
-                           (n, g') = randomR (0, 2^p) g
-                           r = fromRational (n % 2^p)
-                       in (r * d + lo, g')
-  random = randomR (0, 1)
 
diff --git a/test/Random.hs b/test/Random.hs
new file mode 100644
--- /dev/null
+++ b/test/Random.hs
@@ -0,0 +1,22 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module Random
+  ( random
+  ) where
+
+import Test.Tasty (testGroup, TestTree)
+import Test.Tasty.QuickCheck (testProperty, Arbitrary, (==>))
+import System.Random (Random, randoms, randomRs, mkStdGen)
+
+random :: forall a. (Arbitrary a, Show a, Ord a, Fractional a, Random a) => a -> TestTree
+random _ = testGroup "Test Random instance" ts
+  where ts = [ testProperty "randomR range"
+                 (\s l u -> let rs = take 100 (randomRs (l :: a, u) (mkStdGen s))
+                            in l <= u ==> (all (>= l) rs && all (<= u) rs))
+             , testProperty "randomR zero bounds"
+                 (\s l -> let rs = take 100 (randomRs (l :: a, l) (mkStdGen s))
+                          in all (== l) rs)
+             , testProperty "random range"
+                 (\s -> let rs = take 100 (randoms (mkStdGen s)) :: [a]
+                        in all (>= 0) rs && all (< 1) rs)
+             ]
diff --git a/test/Test.hs b/test/Test.hs
--- a/test/Test.hs
+++ b/test/Test.hs
@@ -24,6 +24,7 @@
 import Real (real)
 import RealFrac (realFrac)
 import RealFloat (realFloat)
+import Random (random)
 
 -- How many binary digits to use for comparisons TODO: Test with many different
 -- precisions
@@ -52,6 +53,10 @@
 {-# ANN test_read "HLint: ignore Use camelCase" #-}
 test_read :: [TestTree]
 test_read = [ read' (undefined :: CReal Precision) ]
+
+{-# ANN test_random "HLint: ignore Use camelCase" #-}
+test_random :: [TestTree]
+test_random = [ random (undefined :: CReal Precision) ]
 
 prop_decimalDigits :: Positive Int -> Property
 prop_decimalDigits (Positive p) = let d = decimalDigitsAtPrecision p
