fp-ieee-0.1.0: src/Numeric/Floating/IEEE/Internal/MinMax.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE NoImplicitPrelude #-}
module Numeric.Floating.IEEE.Internal.MinMax where
import MyPrelude
default ()
-- |
-- IEEE 754 @minimum@ operation.
-- @-0@ is smaller than @+0@.
-- Propagates NaNs.
minimum' :: RealFloat a => a -> a -> a
minimum' x y | isNaN x = x + x
| isNaN y = y + y
| x < y || (x == y && isNegativeZero x) = x
| otherwise = y
{-# NOINLINE [1] minimum' #-}
-- |
-- IEEE 754 @minimumNumber@ operation.
-- @-0@ is smaller than @+0@.
-- Treats NaNs as missing data.
minimumNumber :: RealFloat a => a -> a -> a
minimumNumber x y | isNaN x && isNaN y = x + x
| x < y || isNaN y || (x == y && isNegativeZero x) = x
| otherwise = y
{-# NOINLINE [1] minimumNumber #-}
-- |
-- IEEE 754 @maximum@ operation.
-- @-0@ is smaller than @+0@.
-- Propagates NaNs.
maximum' :: RealFloat a => a -> a -> a
maximum' x y | isNaN x = x + x
| isNaN y = y + y
| x < y || (x == y && isNegativeZero x) = y
| otherwise = x
{-# NOINLINE [1] maximum' #-}
-- |
-- IEEE 754 @maximumNumber@ operation.
-- @-0@ is smaller than @+0@.
-- Treats NaNs as missing data.
maximumNumber :: RealFloat a => a -> a -> a
maximumNumber x y | isNaN x && isNaN y = x + x
| x < y || isNaN x || (x == y && isNegativeZero x) = y
| otherwise = x
{-# NOINLINE [1] maximumNumber #-}
-- |
-- IEEE 754 @minimumMagnitude@ operation.
minimumMagnitude :: RealFloat a => a -> a -> a
minimumMagnitude x y | abs x < abs y = x
| abs y < abs x = y
| otherwise = minimum' x y
-- |
-- IEEE 754 @minimumMagnitudeNumber@ operation.
minimumMagnitudeNumber :: RealFloat a => a -> a -> a
minimumMagnitudeNumber x y | abs x < abs y = x
| abs y < abs x = y
| otherwise = minimumNumber x y
-- |
-- IEEE 754 @maximumMagnitude@ operation.
maximumMagnitude :: RealFloat a => a -> a -> a
maximumMagnitude x y | abs x > abs y = x
| abs y > abs x = y
| otherwise = maximum' x y
-- |
-- IEEE 754 @maximumMagnitudeNumber@ operation.
maximumMagnitudeNumber :: RealFloat a => a -> a -> a
maximumMagnitudeNumber x y | abs x > abs y = x
| abs y > abs x = y
| otherwise = maximumNumber x y
#if defined(HAS_FAST_MINMAX)
foreign import ccall unsafe "hs_minimumFloat"
minimumFloat :: Float -> Float -> Float
foreign import ccall unsafe "hs_maximumFloat"
maximumFloat :: Float -> Float -> Float
foreign import ccall unsafe "hs_minimumNumberFloat"
minimumNumberFloat :: Float -> Float -> Float
foreign import ccall unsafe "hs_maximumNumberFloat"
maximumNumberFloat :: Float -> Float -> Float
foreign import ccall unsafe "hs_minimumDouble"
minimumDouble :: Double -> Double -> Double
foreign import ccall unsafe "hs_maximumDouble"
maximumDouble :: Double -> Double -> Double
foreign import ccall unsafe "hs_minimumNumberDouble"
minimumNumberDouble :: Double -> Double -> Double
foreign import ccall unsafe "hs_maximumNumberDouble"
maximumNumberDouble :: Double -> Double -> Double
{-# RULES
"minimum'/Float" minimum' = minimumFloat
"maximum'/Float" maximum' = maximumFloat
"minimumNumber/Float" minimumNumber = minimumNumberFloat
"maximumNumber/Float" maximumNumber = maximumNumberFloat
"minimum'/Double" minimum' = minimumDouble
"maximum'/Double" maximum' = maximumDouble
"minimumNumber/Double" minimumNumber = minimumNumberDouble
"maximumNumber/Double" maximumNumber = maximumNumberDouble
#-}
#else
minimumFloat :: Float -> Float -> Float
maximumFloat :: Float -> Float -> Float
minimumNumberFloat :: Float -> Float -> Float
maximumNumberFloat :: Float -> Float -> Float
minimumDouble :: Double -> Double -> Double
maximumDouble :: Double -> Double -> Double
minimumNumberDouble :: Double -> Double -> Double
maximumNumberDouble :: Double -> Double -> Double
minimumFloat = minimum'
minimumDouble = minimum'
minimumNumberFloat = minimumNumber
minimumNumberDouble = minimumNumber
maximumFloat = maximum'
maximumDouble = maximum'
maximumNumberFloat = maximumNumber
maximumNumberDouble = maximumNumber
#endif