-- | Generally useful generators not present in the upstream release
-- of Hedgehog
module Hedgehog.Gen.Double (doubleInc) where

import Data.Bits (shiftL)
import Data.Word (Word64)
import Hedgehog
import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range

-- | Generates a Double in the inclusive range [0, 1]
doubleInc :: Gen Double
doubleInc :: Gen Double
doubleInc = do
  Word64
b <- Range Word64 -> GenT Identity Word64
forall (m :: * -> *). MonadGen m => Range Word64 -> m Word64
Gen.word64 (Word64 -> Word64 -> Range Word64
forall a. Integral a => a -> a -> Range a
Range.linear Word64
1 Word64
hi)
  Word64
a <- Range Word64 -> GenT Identity Word64
forall (m :: * -> *). MonadGen m => Range Word64 -> m Word64
Gen.word64 (Word64 -> Word64 -> Range Word64
forall a. Integral a => a -> a -> Range a
Range.linear Word64
0 Word64
b)
  Double -> Gen Double
forall a. a -> GenT Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (Double -> Gen Double) -> Double -> Gen Double
forall a b. (a -> b) -> a -> b
$ (Word64 -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
a) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Word64 -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
b)
  where
    hi :: Word64
hi = Word64
2 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
48 :: Word64