{-# 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 :: forall a. RealFloat a => a -> a -> a
maxNum a
x a
y | a
x forall a. Ord a => a -> a -> Bool
>= a
y Bool -> Bool -> 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 :: forall a. RealFloat a => a -> a -> a
minNum a
x a
y | a
x forall a. Ord a => a -> a -> Bool
<= a
y Bool -> Bool -> 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 :: forall a. RealFloat a => a -> a -> a
maxNaN a
x a
y | a
x forall a. Ord a => a -> a -> Bool
>= a
y Bool -> Bool -> 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 :: forall a. RealFloat a => a -> a -> a
minNaN a
x a
y | a
x forall a. Ord a => a -> a -> Bool
<= a
y Bool -> Bool -> 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 Float
x Float
y = Float -> Float -> Int
c_identicalf Float
x Float
y forall a. Eq a => a -> a -> Bool
/= Int
0
{-# INLINE identicalIEEE #-}
infinity :: Float
infinity = Float
1forall a. Fractional a => a -> a -> a
/Float
0
{-# INLINE infinity #-}
nan :: Float
nan = (Float
0forall a. Fractional a => a -> a -> a
/Float
0)
{-# INLINE nan #-}
nanWithPayload :: Word64 -> Float
nanWithPayload Word64
n = Word32 -> Float
c_mknanf (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
n)
{-# INLINE nanWithPayload #-}
maxNaNPayload :: Float -> Word64
maxNaNPayload Float
_ = Word64
0x003FFFFF
{-# INLINE maxNaNPayload #-}
nanPayload :: Float -> Word64
nanPayload Float
x = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ Float -> Word32
c_getnanf Float
x
{-# INLINE nanPayload #-}
minDenormal :: Float
minDenormal = Float
1e-45
{-# INLINE minDenormal #-}
minNormal :: Float
minNormal = Float
1.17549435e-38
{-# INLINE minNormal #-}
maxFinite :: Float
maxFinite = Float
3.40282347e+38
{-# INLINE maxFinite #-}
epsilon :: Float
epsilon = Float
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 CFloat
x CFloat
y = Float -> Float -> Int
c_identicalf (forall a b. (Real a, Fractional b) => a -> b
realToFrac CFloat
x) (forall a b. (Real a, Fractional b) => a -> b
realToFrac CFloat
y) forall a. Eq a => a -> a -> Bool
/= Int
0
{-# INLINE identicalIEEE #-}
infinity :: CFloat
infinity = CFloat
1forall a. Fractional a => a -> a -> a
/CFloat
0
{-# INLINE infinity #-}
nan :: CFloat
nan = (CFloat
0forall a. Fractional a => a -> a -> a
/CFloat
0)
{-# INLINE nan #-}
nanWithPayload :: Word64 -> CFloat
nanWithPayload Word64
n = forall a b. (Real a, Fractional b) => a -> b
realToFrac forall a b. (a -> b) -> a -> b
$ Word32 -> Float
c_mknanf (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
n)
{-# INLINE nanWithPayload #-}
maxNaNPayload :: CFloat -> Word64
maxNaNPayload CFloat
_ = Word64
0x003FFFFF
{-# INLINE maxNaNPayload #-}
nanPayload :: CFloat -> Word64
nanPayload CFloat
x = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ Float -> Word32
c_getnanf (forall a b. (Real a, Fractional b) => a -> b
realToFrac CFloat
x)
{-# INLINE nanPayload #-}
minDenormal :: CFloat
minDenormal = CFloat
1e-45
{-# INLINE minDenormal #-}
minNormal :: CFloat
minNormal = CFloat
1.17549435e-38
{-# INLINE minNormal #-}
maxFinite :: CFloat
maxFinite = CFloat
3.40282347e+38
{-# INLINE maxFinite #-}
epsilon :: CFloat
epsilon = CFloat
1.19209290e-07
{-# INLINE epsilon #-}
copySign :: CFloat -> CFloat -> CFloat
copySign CFloat
x CFloat
y = forall a b. (Real a, Fractional b) => a -> b
realToFrac forall a b. (a -> b) -> a -> b
$ Float -> Float -> Float
c_copysignf (forall a b. (Real a, Fractional b) => a -> b
realToFrac CFloat
x) (forall a b. (Real a, Fractional b) => a -> b
realToFrac CFloat
y)
{-# INLINE copySign #-}
succIEEE :: CFloat -> CFloat
succIEEE CFloat
x = forall a b. (Real a, Fractional b) => a -> b
realToFrac forall a b. (a -> b) -> a -> b
$ Float -> Float
c_ieeesuccf (forall a b. (Real a, Fractional b) => a -> b
realToFrac CFloat
x)
{-# INLINE succIEEE #-}
predIEEE :: CFloat -> CFloat
predIEEE CFloat
x = forall a b. (Real a, Fractional b) => a -> b
realToFrac forall a b. (a -> b) -> a -> b
$ Float -> Float
c_ieeepredf (forall a b. (Real a, Fractional b) => a -> b
realToFrac CFloat
x)
{-# INLINE predIEEE #-}
bisectIEEE :: CFloat -> CFloat -> CFloat
bisectIEEE CFloat
x CFloat
y = forall a b. (Real a, Fractional b) => a -> b
realToFrac forall a b. (a -> b) -> a -> b
$ Float -> Float -> Float
c_ieeemeanf (forall a b. (Real a, Fractional b) => a -> b
realToFrac CFloat
x) (forall a b. (Real a, Fractional b) => a -> b
realToFrac CFloat
y)
{-# INLINE bisectIEEE #-}
sameSignificandBits :: CFloat -> CFloat -> Int
sameSignificandBits CFloat
x CFloat
y = Float -> Float -> Int
c_feqrelf (forall a b. (Real a, Fractional b) => a -> b
realToFrac CFloat
x) (forall a b. (Real a, Fractional b) => a -> b
realToFrac CFloat
y)
{-# INLINE sameSignificandBits #-}
instance IEEE Double where
identicalIEEE :: Double -> Double -> Bool
identicalIEEE Double
x Double
y = Double -> Double -> Int
c_identical Double
x Double
y forall a. Eq a => a -> a -> Bool
/= Int
0
{-# INLINE identicalIEEE #-}
infinity :: Double
infinity = Double
1forall a. Fractional a => a -> a -> a
/Double
0
{-# INLINE infinity #-}
nan :: Double
nan = (Double
0forall a. Fractional a => a -> a -> a
/Double
0)
{-# INLINE nan #-}
nanWithPayload :: Word64 -> Double
nanWithPayload Word64
n = Word64 -> Double
c_mknan Word64
n
{-# INLINE nanWithPayload #-}
maxNaNPayload :: Double -> Word64
maxNaNPayload Double
_ = Word64
0x0007FFFFFFFFFFFF
{-# INLINE maxNaNPayload #-}
nanPayload :: Double -> Word64
nanPayload Double
x = Double -> Word64
c_getnan Double
x
{-# INLINE nanPayload #-}
minDenormal :: Double
minDenormal = Double
5e-324
{-# INLINE minDenormal #-}
minNormal :: Double
minNormal = Double
2.2250738585072014e-308
{-# INLINE minNormal #-}
maxFinite :: Double
maxFinite = Double
1.7976931348623157e+308
{-# INLINE maxFinite #-}
epsilon :: Double
epsilon = Double
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 CDouble
x CDouble
y = Double -> Double -> Int
c_identical (forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
x) (forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
y) forall a. Eq a => a -> a -> Bool
/= Int
0
{-# INLINE identicalIEEE #-}
infinity :: CDouble
infinity = CDouble
1forall a. Fractional a => a -> a -> a
/CDouble
0
{-# INLINE infinity #-}
nan :: CDouble
nan = (CDouble
0forall a. Fractional a => a -> a -> a
/CDouble
0)
{-# INLINE nan #-}
nanWithPayload :: Word64 -> CDouble
nanWithPayload Word64
n = forall a b. (Real a, Fractional b) => a -> b
realToFrac forall a b. (a -> b) -> a -> b
$ Word64 -> Double
c_mknan Word64
n
{-# INLINE nanWithPayload #-}
maxNaNPayload :: CDouble -> Word64
maxNaNPayload CDouble
_ = Word64
0x0007FFFFFFFFFFFF
{-# INLINE maxNaNPayload #-}
nanPayload :: CDouble -> Word64
nanPayload CDouble
x = Double -> Word64
c_getnan (forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
x)
{-# INLINE nanPayload #-}
minDenormal :: CDouble
minDenormal = CDouble
5e-324
{-# INLINE minDenormal #-}
minNormal :: CDouble
minNormal = CDouble
2.2250738585072014e-308
{-# INLINE minNormal #-}
maxFinite :: CDouble
maxFinite = CDouble
1.7976931348623157e+308
{-# INLINE maxFinite #-}
epsilon :: CDouble
epsilon = CDouble
2.2204460492503131e-16
{-# INLINE epsilon #-}
succIEEE :: CDouble -> CDouble
succIEEE CDouble
x = forall a b. (Real a, Fractional b) => a -> b
realToFrac forall a b. (a -> b) -> a -> b
$ Double -> Double
c_ieeesucc (forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
x)
{-# INLINE succIEEE #-}
copySign :: CDouble -> CDouble -> CDouble
copySign CDouble
x CDouble
y = forall a b. (Real a, Fractional b) => a -> b
realToFrac forall a b. (a -> b) -> a -> b
$ Double -> Double -> Double
c_copysign (forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
x) (forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
y)
{-# INLINE copySign #-}
predIEEE :: CDouble -> CDouble
predIEEE CDouble
x = forall a b. (Real a, Fractional b) => a -> b
realToFrac forall a b. (a -> b) -> a -> b
$ Double -> Double
c_ieeepred (forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
x)
{-# INLINE predIEEE #-}
bisectIEEE :: CDouble -> CDouble -> CDouble
bisectIEEE CDouble
x CDouble
y = forall a b. (Real a, Fractional b) => a -> b
realToFrac forall a b. (a -> b) -> a -> b
$ Double -> Double -> Double
c_ieeemean (forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
x) (forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
y)
{-# INLINE bisectIEEE #-}
sameSignificandBits :: CDouble -> CDouble -> Int
sameSignificandBits CDouble
x CDouble
y = Double -> Double -> Int
c_feqrel (forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
x) (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