fp-ieee-0.1.0: test/MinMaxSpec.hs
module MinMaxSpec where
import Data.Coerce
import Data.Functor.Identity
import Data.Proxy
import Numeric.Floating.IEEE
import Numeric.Floating.IEEE.Internal
import Numeric.Floating.IEEE.NaN (RealFloatNaN(..))
import Test.Hspec
import Test.Hspec.QuickCheck
import Test.QuickCheck
import Util
default ()
isQuietNaN :: RealFloatNaN a => a -> Bool
isQuietNaN x = isNaN x && not (isSignaling x)
prop_minimum :: RealFloatNaN a => Proxy a -> (a -> a -> a) -> Property
prop_minimum _ m =
let sNaN = setPayloadSignaling 1
qNaN = setPayload 1
in conjoin
[ counterexample "(1,3)" $ m 1 3 `sameFloatP` 1
, counterexample "(1,-1)" $ m 1 (-1) `sameFloatP` (-1)
, counterexample "(0,0)" $ m 0 0 `sameFloatP` 0
, counterexample "(0,-0)" $ m 0 (-0) `sameFloatP` (-0)
, counterexample "(-0,0)" $ m (-0) 0 `sameFloatP` (-0)
, counterexample "(-0,-0)" $ m (-0) (-0) `sameFloatP` (-0)
, counterexample "(sNaN,sNaN)" $ isQuietNaN (m sNaN sNaN)
, counterexample "(sNaN,qNaN)" $ isQuietNaN (m sNaN qNaN)
, counterexample "(qNaN,sNaN)" $ isQuietNaN (m qNaN sNaN)
, counterexample "(qNaN,qNaN)" $ isQuietNaN (m qNaN qNaN)
, counterexample "(sNaN,1.0)" $ isQuietNaN (m sNaN 1.0)
, counterexample "(1.0,sNaN)" $ isQuietNaN (m 1.0 sNaN)
, counterexample "(qNaN,1.0)" $ isQuietNaN (m qNaN 1.0)
, counterexample "(1.0,qNaN)" $ isQuietNaN (m 1.0 qNaN)
]
prop_maximum :: RealFloatNaN a => Proxy a -> (a -> a -> a) -> Property
prop_maximum _ m =
let sNaN = setPayloadSignaling 1
qNaN = setPayload 1
in conjoin
[ counterexample "(1,3)" $ m 1 3 `sameFloatP` 3
, counterexample "(1,-1)" $ m 1 (-1) `sameFloatP` 1
, counterexample "(0,0)" $ m 0 0 `sameFloatP` 0
, counterexample "(0,-0)" $ m 0 (-0) `sameFloatP` 0
, counterexample "(-0,0)" $ m (-0) 0 `sameFloatP` 0
, counterexample "(-0,-0)" $ m (-0) (-0) `sameFloatP` (-0)
, counterexample "(sNaN,sNaN)" $ isQuietNaN (m sNaN sNaN)
, counterexample "(sNaN,qNaN)" $ isQuietNaN (m sNaN qNaN)
, counterexample "(qNaN,sNaN)" $ isQuietNaN (m qNaN sNaN)
, counterexample "(qNaN,qNaN)" $ isQuietNaN (m qNaN qNaN)
, counterexample "(sNaN,1.0)" $ isQuietNaN (m sNaN 1.0)
, counterexample "(1.0,sNaN)" $ isQuietNaN (m 1.0 sNaN)
, counterexample "(qNaN,1.0)" $ isQuietNaN (m qNaN 1.0)
, counterexample "(1.0,qNaN)" $ isQuietNaN (m 1.0 qNaN)
]
prop_minimumNumber :: RealFloatNaN a => Proxy a -> (a -> a -> a) -> Property
prop_minimumNumber _ m =
let sNaN = setPayloadSignaling 1
qNaN = setPayload 1
in conjoin
[ counterexample "(1,3)" $ m 1 3 `sameFloatP` 1
, counterexample "(1,-1)" $ m 1 (-1) `sameFloatP` (-1)
, counterexample "(0,0)" $ m 0 0 `sameFloatP` 0
, counterexample "(0,-0)" $ m 0 (-0) `sameFloatP` (-0)
, counterexample "(-0,0)" $ m (-0) 0 `sameFloatP` (-0)
, counterexample "(-0,-0)" $ m (-0) (-0) `sameFloatP` (-0)
, counterexample "(sNaN,sNaN)" $ isQuietNaN (m sNaN sNaN)
, counterexample "(sNaN,qNaN)" $ isQuietNaN (m sNaN qNaN)
, counterexample "(qNaN,sNaN)" $ isQuietNaN (m qNaN sNaN)
, counterexample "(qNaN,qNaN)" $ isQuietNaN (m qNaN qNaN)
, counterexample "(sNaN,1.0)" $ m sNaN 1.0 `sameFloatP` 1.0
, counterexample "(1.0,sNaN)" $ m 1.0 sNaN `sameFloatP` 1.0
, counterexample "(qNaN,1.0)" $ m qNaN 1.0 `sameFloatP` 1.0
, counterexample "(1.0,qNaN)" $ m 1.0 qNaN `sameFloatP` 1.0
]
prop_maximumNumber :: RealFloatNaN a => Proxy a -> (a -> a -> a) -> Property
prop_maximumNumber _ m =
let sNaN = setPayloadSignaling 1
qNaN = setPayload 1
in conjoin
[ counterexample "(1,3)" $ m 1 3 `sameFloatP` 3
, counterexample "(1,-1)" $ m 1 (-1) `sameFloatP` 1
, counterexample "(0,0)" $ m 0 0 `sameFloatP` 0
, counterexample "(0,-0)" $ m 0 (-0) `sameFloatP` 0
, counterexample "(-0,0)" $ m (-0) 0 `sameFloatP` 0
, counterexample "(-0,-0)" $ m (-0) (-0) `sameFloatP` (-0)
, counterexample "(sNaN,sNaN)" $ isQuietNaN (m sNaN sNaN)
, counterexample "(sNaN,qNaN)" $ isQuietNaN (m sNaN qNaN)
, counterexample "(qNaN,sNaN)" $ isQuietNaN (m qNaN sNaN)
, counterexample "(qNaN,qNaN)" $ isQuietNaN (m qNaN qNaN)
, counterexample "(sNaN,1.0)" $ m sNaN 1.0 `sameFloatP` 1.0
, counterexample "(1.0,sNaN)" $ m 1.0 sNaN `sameFloatP` 1.0
, counterexample "(qNaN,1.0)" $ m qNaN 1.0 `sameFloatP` 1.0
, counterexample "(1.0,qNaN)" $ m 1.0 qNaN `sameFloatP` 1.0
]
{-# NOINLINE spec #-}
spec :: Spec
spec = do
describe "Float" $ do
let proxy :: Proxy Float
proxy = Proxy
prop "minimum'" $ prop_minimum proxy minimum'
prop "minimum' (generic)" $ prop_minimum proxy (coerce (minimum' :: Identity Float -> Identity Float -> Identity Float))
prop "minimumFloat" $ prop_minimum proxy minimumFloat
prop "minimumNumber" $ prop_minimumNumber proxy minimumNumber
prop "minimumNumber (generic)" $ prop_minimumNumber proxy (coerce (minimumNumber :: Identity Float -> Identity Float -> Identity Float))
prop "minimumNumberFloat" $ prop_minimumNumber proxy minimumNumberFloat
prop "maximum'" $ prop_maximum proxy maximum'
prop "maximum' (generic)" $ prop_maximum proxy (coerce (maximum' :: Identity Float -> Identity Float -> Identity Float))
prop "maximumFloat" $ prop_maximum proxy maximumFloat
prop "maximumNumber" $ prop_maximumNumber proxy maximumNumber
prop "maximumNumber (generic)" $ prop_maximumNumber proxy (coerce (maximumNumber :: Identity Float -> Identity Float -> Identity Float))
prop "maximumNumberFloat" $ prop_maximumNumber proxy maximumNumberFloat
describe "Double" $ do
let proxy :: Proxy Double
proxy = Proxy
prop "minimum'" $ prop_minimum proxy minimum'
prop "minimum' (generic)" $ prop_minimum proxy (coerce (minimum' :: Identity Double -> Identity Double -> Identity Double))
prop "minimumDouble" $ prop_minimum proxy minimumDouble
prop "minimumNumber" $ prop_minimumNumber proxy minimumNumber
prop "minimumNumber (generic)" $ prop_minimumNumber proxy (coerce (minimumNumber :: Identity Double -> Identity Double -> Identity Double))
prop "minimumNumberDouble" $ prop_minimumNumber proxy minimumNumberDouble
prop "maximum'" $ prop_maximum proxy maximum'
prop "maximum' (generic)" $ prop_maximum proxy (coerce (maximum' :: Identity Double -> Identity Double -> Identity Double))
prop "maximumDouble" $ prop_maximum proxy maximumDouble
prop "maximumNumber" $ prop_maximumNumber proxy maximumNumber
prop "maximumNumber (generic)" $ prop_maximumNumber proxy (coerce (maximumNumber :: Identity Double -> Identity Double -> Identity Double))
prop "maximumNumberDouble" $ prop_maximumNumber proxy maximumNumberDouble