exact-real-0.7.1.0: test/RealFloat.hs
{-# LANGUAGE ScopedTypeVariables #-}
module RealFloat
( realFloat
) where
import Data.Ratio.Extra ()
import Test.QuickCheck.Checkers (EqProp, (=-=), inverseL)
import Test.Tasty (testGroup, TestTree)
import Test.Tasty.QuickCheck (testProperty, Arbitrary, (==>))
realFloat :: forall a. (Arbitrary a, EqProp a, Show a, RealFloat a) =>
a -> TestTree
realFloat x = testGroup "Test RealFloat instance" ts
where ts = [ decodeFloatLaws "decodeFloat laws" x
, testProperty "encodeFloat decodeFloat left inverse"
(inverseL (uncurry encodeFloat) (decodeFloat :: a -> (Integer, Int)))
, testProperty "scaleFloat definition"
(\y i -> let r = floatRadix y
in scaleFloat i (y::a) =-= y * fromIntegral r ^^ i)
, atan2Laws "atan2 laws" x
]
decodeFloatLaws :: forall a. (Arbitrary a, EqProp a, Show a, RealFloat a) =>
String -> a -> TestTree
decodeFloatLaws s _ = testGroup s ts
where ts = [ testProperty "x = m*b^^n"
(\x -> let (m, n) = decodeFloat (x :: a)
b = floatRadix x
in not (isNaN x || isInfinite x) ==>
(x =-= fromInteger m * fromInteger b ^^ n))
]
atan2Laws :: forall a. (Arbitrary a, EqProp a, Show a, RealFloat a) =>
String -> a -> TestTree
atan2Laws s _ = testGroup s ts
where ts = [ testProperty "atan2 range" (\y x -> let θ = atan2 y (x :: a)
in abs θ <= pi)
, testProperty "atan2 y 1 = atan y" (\y -> let θ = atan2 y (1 :: a)
in θ =-= atan y)
]