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 x y | x >= y || isNaN y = x
| otherwise = y
minNum :: (RealFloat a) => a -> a -> a
minNum x y | x <= y || isNaN y = x
| otherwise = y
maxNaN :: (RealFloat a) => a -> a -> a
maxNaN x y | x >= y || isNaN x = x
| otherwise = y
minNaN :: (RealFloat a) => a -> a -> a
minNaN x y | x <= y || isNaN x = x
| otherwise = y
instance IEEE Float where
identicalIEEE x y = c_identicalf x y /= 0
infinity = 1/0
nan = (0/0)
nanWithPayload n = c_mknanf (fromIntegral n)
maxNaNPayload _ = 0x003FFFFF
nanPayload x = fromIntegral $ c_getnanf x
minDenormal = 1e-45
minNormal = 1.17549435e-38
maxFinite = 3.40282347e+38
epsilon = 1.19209290e-07
copySign = c_copysignf
succIEEE = c_ieeesuccf
predIEEE = c_ieeepredf
bisectIEEE = c_ieeemeanf
sameSignificandBits = c_feqrelf
instance IEEE CFloat where
identicalIEEE x y = c_identicalf (realToFrac x) (realToFrac y) /= 0
infinity = 1/0
nan = (0/0)
nanWithPayload n = realToFrac $ c_mknanf (fromIntegral n)
maxNaNPayload _ = 0x003FFFFF
nanPayload x = fromIntegral $ c_getnanf (realToFrac x)
minDenormal = 1e-45
minNormal = 1.17549435e-38
maxFinite = 3.40282347e+38
epsilon = 1.19209290e-07
copySign x y = realToFrac $ c_copysignf (realToFrac x) (realToFrac y)
succIEEE x = realToFrac $ c_ieeesuccf (realToFrac x)
predIEEE x = realToFrac $ c_ieeepredf (realToFrac x)
bisectIEEE x y = realToFrac $ c_ieeemeanf (realToFrac x) (realToFrac y)
sameSignificandBits x y = c_feqrelf (realToFrac x) (realToFrac y)
instance IEEE Double where
identicalIEEE x y = c_identical x y /= 0
infinity = 1/0
nan = (0/0)
nanWithPayload n = c_mknan n
maxNaNPayload _ = 0x0007FFFFFFFFFFFF
nanPayload x = c_getnan x
minDenormal = 5e-324
minNormal = 2.2250738585072014e-308
maxFinite = 1.7976931348623157e+308
epsilon = 2.2204460492503131e-16
copySign = c_copysign
succIEEE = c_ieeesucc
predIEEE = c_ieeepred
bisectIEEE = c_ieeemean
sameSignificandBits = c_feqrel
instance IEEE CDouble where
identicalIEEE x y = c_identical (realToFrac x) (realToFrac y) /= 0
infinity = 1/0
nan = (0/0)
nanWithPayload n = realToFrac $ c_mknan n
maxNaNPayload _ = 0x0007FFFFFFFFFFFF
nanPayload x = c_getnan (realToFrac x)
minDenormal = 5e-324
minNormal = 2.2250738585072014e-308
maxFinite = 1.7976931348623157e+308
epsilon = 2.2204460492503131e-16
succIEEE x = realToFrac $ c_ieeesucc (realToFrac x)
copySign x y = realToFrac $ c_copysign (realToFrac x) (realToFrac y)
predIEEE x = realToFrac $ c_ieeepred (realToFrac x)
bisectIEEE x y = realToFrac $ c_ieeemean (realToFrac x) (realToFrac y)
sameSignificandBits x y = c_feqrel (realToFrac x) (realToFrac y)
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