{-# LANGUAGE ForeignFunctionInterface #-}
module Numeric.IEEE (
IEEE(..),
minNum,
maxNum,
minNaN,
maxNaN,
) where
import Data.Word
import Foreign.C.Types( CFloat, CDouble )
class (RealFloat a) => IEEE a where
infinity :: a
minDenormal :: a
minNormal :: a
maxFinite :: a
epsilon :: a
copySign :: a -> a -> a
identicalIEEE :: a -> a -> Bool
succIEEE :: a -> a
predIEEE :: a -> a
bisectIEEE :: a -> a -> a
sameSignificandBits :: a -> a -> Int
nan :: a
nanWithPayload :: Word64 -> a
maxNaNPayload :: a -> Word64
nanPayload :: a -> Word64
maxNum :: (RealFloat a) => a -> a -> a
maxNum :: a -> a -> a
maxNum x :: a
x y :: a
y | a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
y Bool -> Bool -> Bool
|| a -> Bool
forall a. RealFloat a => a -> Bool
isNaN a
y = a
x
| Bool
otherwise = a
y
{-# INLINE maxNum #-}
minNum :: (RealFloat a) => a -> a -> a
minNum :: a -> a -> a
minNum x :: a
x y :: a
y | a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
y Bool -> Bool -> Bool
|| a -> Bool
forall a. RealFloat a => a -> Bool
isNaN a
y = a
x
| Bool
otherwise = a
y
{-# INLINE minNum #-}
maxNaN :: (RealFloat a) => a -> a -> a
maxNaN :: a -> a -> a
maxNaN x :: a
x y :: a
y | a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
y Bool -> Bool -> Bool
|| a -> Bool
forall a. RealFloat a => a -> Bool
isNaN a
x = a
x
| Bool
otherwise = a
y
{-# INLINE maxNaN #-}
minNaN :: (RealFloat a) => a -> a -> a
minNaN :: a -> a -> a
minNaN x :: a
x y :: a
y | a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
y Bool -> Bool -> Bool
|| a -> Bool
forall a. RealFloat a => a -> Bool
isNaN a
x = a
x
| Bool
otherwise = a
y
{-# INLINE minNaN #-}
instance IEEE Float where
identicalIEEE :: Float -> Float -> Bool
identicalIEEE x :: Float
x y :: Float
y = Float -> Float -> Int
c_identicalf Float
x Float
y Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= 0
{-# INLINE identicalIEEE #-}
infinity :: Float
infinity = 1Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/0
{-# INLINE infinity #-}
nan :: Float
nan = (0Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/0)
{-# INLINE nan #-}
nanWithPayload :: Word64 -> Float
nanWithPayload n :: Word64
n = Word32 -> Float
c_mknanf (Word64 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
n)
{-# INLINE nanWithPayload #-}
maxNaNPayload :: Float -> Word64
maxNaNPayload _ = 0x003FFFFF
{-# INLINE maxNaNPayload #-}
nanPayload :: Float -> Word64
nanPayload x :: Float
x = Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Word64) -> Word32 -> Word64
forall a b. (a -> b) -> a -> b
$ Float -> Word32
c_getnanf Float
x
{-# INLINE nanPayload #-}
minDenormal :: Float
minDenormal = 1e-45
{-# INLINE minDenormal #-}
minNormal :: Float
minNormal = 1.17549435e-38
{-# INLINE minNormal #-}
maxFinite :: Float
maxFinite = 3.40282347e+38
{-# INLINE maxFinite #-}
epsilon :: Float
epsilon = 1.19209290e-07
{-# INLINE epsilon #-}
copySign :: Float -> Float -> Float
copySign = Float -> Float -> Float
c_copysignf
{-# INLINE copySign #-}
succIEEE :: Float -> Float
succIEEE = Float -> Float
c_ieeesuccf
{-# INLINE succIEEE #-}
predIEEE :: Float -> Float
predIEEE = Float -> Float
c_ieeepredf
{-# INLINE predIEEE #-}
bisectIEEE :: Float -> Float -> Float
bisectIEEE = Float -> Float -> Float
c_ieeemeanf
{-# INLINE bisectIEEE #-}
sameSignificandBits :: Float -> Float -> Int
sameSignificandBits = Float -> Float -> Int
c_feqrelf
{-# INLINE sameSignificandBits #-}
instance IEEE CFloat where
identicalIEEE :: CFloat -> CFloat -> Bool
identicalIEEE x :: CFloat
x y :: CFloat
y = Float -> Float -> Int
c_identicalf (CFloat -> Float
forall a b. (Real a, Fractional b) => a -> b
realToFrac CFloat
x) (CFloat -> Float
forall a b. (Real a, Fractional b) => a -> b
realToFrac CFloat
y) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= 0
{-# INLINE identicalIEEE #-}
infinity :: CFloat
infinity = 1CFloat -> CFloat -> CFloat
forall a. Fractional a => a -> a -> a
/0
{-# INLINE infinity #-}
nan :: CFloat
nan = (0CFloat -> CFloat -> CFloat
forall a. Fractional a => a -> a -> a
/0)
{-# INLINE nan #-}
nanWithPayload :: Word64 -> CFloat
nanWithPayload n :: Word64
n = Float -> CFloat
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Float -> CFloat) -> Float -> CFloat
forall a b. (a -> b) -> a -> b
$ Word32 -> Float
c_mknanf (Word64 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
n)
{-# INLINE nanWithPayload #-}
maxNaNPayload :: CFloat -> Word64
maxNaNPayload _ = 0x003FFFFF
{-# INLINE maxNaNPayload #-}
nanPayload :: CFloat -> Word64
nanPayload x :: CFloat
x = Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Word64) -> Word32 -> Word64
forall a b. (a -> b) -> a -> b
$ Float -> Word32
c_getnanf (CFloat -> Float
forall a b. (Real a, Fractional b) => a -> b
realToFrac CFloat
x)
{-# INLINE nanPayload #-}
minDenormal :: CFloat
minDenormal = 1e-45
{-# INLINE minDenormal #-}
minNormal :: CFloat
minNormal = 1.17549435e-38
{-# INLINE minNormal #-}
maxFinite :: CFloat
maxFinite = 3.40282347e+38
{-# INLINE maxFinite #-}
epsilon :: CFloat
epsilon = 1.19209290e-07
{-# INLINE epsilon #-}
copySign :: CFloat -> CFloat -> CFloat
copySign x :: CFloat
x y :: CFloat
y = Float -> CFloat
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Float -> CFloat) -> Float -> CFloat
forall a b. (a -> b) -> a -> b
$ Float -> Float -> Float
c_copysignf (CFloat -> Float
forall a b. (Real a, Fractional b) => a -> b
realToFrac CFloat
x) (CFloat -> Float
forall a b. (Real a, Fractional b) => a -> b
realToFrac CFloat
y)
{-# INLINE copySign #-}
succIEEE :: CFloat -> CFloat
succIEEE x :: CFloat
x = Float -> CFloat
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Float -> CFloat) -> Float -> CFloat
forall a b. (a -> b) -> a -> b
$ Float -> Float
c_ieeesuccf (CFloat -> Float
forall a b. (Real a, Fractional b) => a -> b
realToFrac CFloat
x)
{-# INLINE succIEEE #-}
predIEEE :: CFloat -> CFloat
predIEEE x :: CFloat
x = Float -> CFloat
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Float -> CFloat) -> Float -> CFloat
forall a b. (a -> b) -> a -> b
$ Float -> Float
c_ieeepredf (CFloat -> Float
forall a b. (Real a, Fractional b) => a -> b
realToFrac CFloat
x)
{-# INLINE predIEEE #-}
bisectIEEE :: CFloat -> CFloat -> CFloat
bisectIEEE x :: CFloat
x y :: CFloat
y = Float -> CFloat
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Float -> CFloat) -> Float -> CFloat
forall a b. (a -> b) -> a -> b
$ Float -> Float -> Float
c_ieeemeanf (CFloat -> Float
forall a b. (Real a, Fractional b) => a -> b
realToFrac CFloat
x) (CFloat -> Float
forall a b. (Real a, Fractional b) => a -> b
realToFrac CFloat
y)
{-# INLINE bisectIEEE #-}
sameSignificandBits :: CFloat -> CFloat -> Int
sameSignificandBits x :: CFloat
x y :: CFloat
y = Float -> Float -> Int
c_feqrelf (CFloat -> Float
forall a b. (Real a, Fractional b) => a -> b
realToFrac CFloat
x) (CFloat -> Float
forall a b. (Real a, Fractional b) => a -> b
realToFrac CFloat
y)
{-# INLINE sameSignificandBits #-}
instance IEEE Double where
identicalIEEE :: Double -> Double -> Bool
identicalIEEE x :: Double
x y :: Double
y = Double -> Double -> Int
c_identical Double
x Double
y Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= 0
{-# INLINE identicalIEEE #-}
infinity :: Double
infinity = 1Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/0
{-# INLINE infinity #-}
nan :: Double
nan = (0Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/0)
{-# INLINE nan #-}
nanWithPayload :: Word64 -> Double
nanWithPayload n :: Word64
n = Word64 -> Double
c_mknan Word64
n
{-# INLINE nanWithPayload #-}
maxNaNPayload :: Double -> Word64
maxNaNPayload _ = 0x0007FFFFFFFFFFFF
{-# INLINE maxNaNPayload #-}
nanPayload :: Double -> Word64
nanPayload x :: Double
x = Double -> Word64
c_getnan Double
x
{-# INLINE nanPayload #-}
minDenormal :: Double
minDenormal = 5e-324
{-# INLINE minDenormal #-}
minNormal :: Double
minNormal = 2.2250738585072014e-308
{-# INLINE minNormal #-}
maxFinite :: Double
maxFinite = 1.7976931348623157e+308
{-# INLINE maxFinite #-}
epsilon :: Double
epsilon = 2.2204460492503131e-16
{-# INLINE epsilon #-}
copySign :: Double -> Double -> Double
copySign = Double -> Double -> Double
c_copysign
{-# INLINE copySign #-}
succIEEE :: Double -> Double
succIEEE = Double -> Double
c_ieeesucc
{-# INLINE succIEEE #-}
predIEEE :: Double -> Double
predIEEE = Double -> Double
c_ieeepred
{-# INLINE predIEEE #-}
bisectIEEE :: Double -> Double -> Double
bisectIEEE = Double -> Double -> Double
c_ieeemean
{-# INLINE bisectIEEE #-}
sameSignificandBits :: Double -> Double -> Int
sameSignificandBits = Double -> Double -> Int
c_feqrel
{-# INLINE sameSignificandBits #-}
instance IEEE CDouble where
identicalIEEE :: CDouble -> CDouble -> Bool
identicalIEEE x :: CDouble
x y :: CDouble
y = Double -> Double -> Int
c_identical (CDouble -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
x) (CDouble -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
y) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= 0
{-# INLINE identicalIEEE #-}
infinity :: CDouble
infinity = 1CDouble -> CDouble -> CDouble
forall a. Fractional a => a -> a -> a
/0
{-# INLINE infinity #-}
nan :: CDouble
nan = (0CDouble -> CDouble -> CDouble
forall a. Fractional a => a -> a -> a
/0)
{-# INLINE nan #-}
nanWithPayload :: Word64 -> CDouble
nanWithPayload n :: Word64
n = Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Double -> CDouble) -> Double -> CDouble
forall a b. (a -> b) -> a -> b
$ Word64 -> Double
c_mknan Word64
n
{-# INLINE nanWithPayload #-}
maxNaNPayload :: CDouble -> Word64
maxNaNPayload _ = 0x0007FFFFFFFFFFFF
{-# INLINE maxNaNPayload #-}
nanPayload :: CDouble -> Word64
nanPayload x :: CDouble
x = Double -> Word64
c_getnan (CDouble -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
x)
{-# INLINE nanPayload #-}
minDenormal :: CDouble
minDenormal = 5e-324
{-# INLINE minDenormal #-}
minNormal :: CDouble
minNormal = 2.2250738585072014e-308
{-# INLINE minNormal #-}
maxFinite :: CDouble
maxFinite = 1.7976931348623157e+308
{-# INLINE maxFinite #-}
epsilon :: CDouble
epsilon = 2.2204460492503131e-16
{-# INLINE epsilon #-}
succIEEE :: CDouble -> CDouble
succIEEE x :: CDouble
x = Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Double -> CDouble) -> Double -> CDouble
forall a b. (a -> b) -> a -> b
$ Double -> Double
c_ieeesucc (CDouble -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
x)
{-# INLINE succIEEE #-}
copySign :: CDouble -> CDouble -> CDouble
copySign x :: CDouble
x y :: CDouble
y = Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Double -> CDouble) -> Double -> CDouble
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Double
c_copysign (CDouble -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
x) (CDouble -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
y)
{-# INLINE copySign #-}
predIEEE :: CDouble -> CDouble
predIEEE x :: CDouble
x = Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Double -> CDouble) -> Double -> CDouble
forall a b. (a -> b) -> a -> b
$ Double -> Double
c_ieeepred (CDouble -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
x)
{-# INLINE predIEEE #-}
bisectIEEE :: CDouble -> CDouble -> CDouble
bisectIEEE x :: CDouble
x y :: CDouble
y = Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Double -> CDouble) -> Double -> CDouble
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Double
c_ieeemean (CDouble -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
x) (CDouble -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
y)
{-# INLINE bisectIEEE #-}
sameSignificandBits :: CDouble -> CDouble -> Int
sameSignificandBits x :: CDouble
x y :: CDouble
y = Double -> Double -> Int
c_feqrel (CDouble -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
x) (CDouble -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
y)
{-# INLINE sameSignificandBits #-}
foreign import ccall unsafe "identical"
c_identical :: Double -> Double -> Int
foreign import ccall unsafe "identicalf"
c_identicalf :: Float -> Float -> Int
foreign import ccall unsafe "feqrel"
c_feqrel :: Double -> Double -> Int
foreign import ccall unsafe "feqrelf"
c_feqrelf :: Float -> Float -> Int
foreign import ccall unsafe "ieeesucc"
c_ieeesucc :: Double -> Double
foreign import ccall unsafe "ieeesuccf"
c_ieeesuccf :: Float -> Float
foreign import ccall unsafe "ieeepred"
c_ieeepred :: Double -> Double
foreign import ccall unsafe "ieeepredf"
c_ieeepredf :: Float -> Float
foreign import ccall unsafe "ieeemean"
c_ieeemean :: Double -> Double -> Double
foreign import ccall unsafe "ieeemeanf"
c_ieeemeanf :: Float -> Float -> Float
foreign import ccall unsafe "copysign"
c_copysign :: Double -> Double -> Double
foreign import ccall unsafe "copysignf"
c_copysignf :: Float -> Float -> Float
foreign import ccall unsafe "mknan"
c_mknan :: Word64 -> Double
foreign import ccall unsafe "getnan"
c_getnan :: Double -> Word64
foreign import ccall unsafe "mknanf"
c_mknanf :: Word32 -> Float
foreign import ccall unsafe "getnanf"
c_getnanf :: Float -> Word32