{-# LINE 1 "src/Data/Float.hsc" #-}
{-# LANGUAGE CPP, ForeignFunctionInterface #-}
{-# LANGUAGE FlexibleContexts #-}
module Data.Float (
Float
, Double
, module Data.Float
) where
import Data.Bits ((.&.))
import Data.Connection
import Data.Function (on)
import Data.Int
import Data.Prd
import Data.Semifield
import Data.Semigroup.Join
import Data.Semigroup.Meet
import Data.Semiring
import Data.Word
import Foreign hiding (shift)
import Foreign.C
import GHC.Float as F
import Prelude (Double,realToFrac,fromIntegral,($),return,IO)
import Prelude hiding (Ord(..), Num(..), Fractional(..), Floating(..), (^^), (^), RealFloat(..), Real(..), Enum(..))
import System.IO.Unsafe (unsafePerformIO)
import qualified Prelude as P
{-# LINE 28 "Foreign/C/Math/Double.hsc" #-}
acos :: Double -> Double
acos x = realToFrac (c_acos (realToFrac x))
{-# INLINE acos #-}
foreign import ccall unsafe "math.h acos"
c_acos :: CDouble -> CDouble
asin :: Double -> Double
asin x = realToFrac (c_asin (realToFrac x))
{-# INLINE asin #-}
foreign import ccall unsafe "math.h asin"
c_asin :: CDouble -> CDouble
atan :: Double -> Double
atan x = realToFrac (c_atan (realToFrac x))
{-# INLINE atan #-}
foreign import ccall unsafe "math.h atan"
c_atan :: CDouble -> CDouble
atan2 :: Double -> Double -> Double
atan2 x y = realToFrac (c_atan2 (realToFrac x) (realToFrac y))
{-# INLINE atan2 #-}
foreign import ccall unsafe "math.h atan2"
c_atan2 :: CDouble -> CDouble -> CDouble
cos :: Double -> Double
cos x = realToFrac (c_cos (realToFrac x))
{-# INLINE cos #-}
foreign import ccall unsafe "math.h cos"
c_cos :: CDouble -> CDouble
sin :: Double -> Double
sin x = realToFrac (c_sin (realToFrac x))
{-# INLINE sin #-}
foreign import ccall unsafe "math.h sin"
c_sin :: CDouble -> CDouble
tan :: Double -> Double
tan x = realToFrac (c_tan (realToFrac x))
{-# INLINE tan #-}
foreign import ccall unsafe "math.h tan"
c_tan :: CDouble -> CDouble
cosh :: Double -> Double
cosh x = realToFrac (c_cosh (realToFrac x))
{-# INLINE cosh #-}
foreign import ccall unsafe "math.h cosh"
c_cosh :: CDouble -> CDouble
sinh :: Double -> Double
sinh x = realToFrac (c_sinh (realToFrac x))
{-# INLINE sinh #-}
foreign import ccall unsafe "math.h sinh"
c_sinh :: CDouble -> CDouble
tanh :: Double -> Double
tanh x = realToFrac (c_tanh (realToFrac x))
{-# INLINE tanh #-}
foreign import ccall unsafe "math.h tanh"
c_tanh :: CDouble -> CDouble
exp :: Double -> Double
exp x = realToFrac (c_exp (realToFrac x))
{-# INLINE exp #-}
foreign import ccall unsafe "math.h exp"
c_exp :: CDouble -> CDouble
frexp :: Double -> (Double,Int)
frexp x = unsafePerformIO $
alloca $ \p -> do
d <- c_frexp (realToFrac x) p
i <- peek p
return (realToFrac d, fromIntegral i)
foreign import ccall unsafe "math.h frexp"
c_frexp :: CDouble -> Ptr CInt -> IO Double
ldexp :: Double -> Int -> Double
ldexp x i = realToFrac (c_ldexp (realToFrac x) (fromIntegral i))
{-# INLINE ldexp #-}
foreign import ccall unsafe "math.h ldexp"
c_ldexp :: CDouble -> CInt -> Double
log :: Double -> Double
log x = realToFrac (c_log (realToFrac x))
{-# INLINE log #-}
foreign import ccall unsafe "math.h log"
c_log :: CDouble -> CDouble
log10 :: Double -> Double
log10 x = realToFrac (c_log10 (realToFrac x))
{-# INLINE log10 #-}
foreign import ccall unsafe "math.h log10"
c_log10 :: CDouble -> CDouble
modf :: Double -> (Double,Double)
modf x = unsafePerformIO $
alloca $ \p -> do
d <- c_modf (realToFrac x) p
i <- peek p
return (realToFrac d, realToFrac i)
foreign import ccall unsafe "math.h modf"
c_modf :: CDouble -> Ptr CDouble -> IO CDouble
pow :: Double -> Double -> Double
pow x y = realToFrac (c_pow (realToFrac x) (realToFrac y))
{-# INLINE pow #-}
foreign import ccall unsafe "math.h pow"
c_pow :: CDouble -> CDouble -> CDouble
sqrt :: Double -> Double
sqrt x = realToFrac (c_sqrt (realToFrac x))
{-# INLINE sqrt #-}
foreign import ccall unsafe "math.h sqrt"
c_sqrt :: CDouble -> CDouble
ceil :: Double -> Double
ceil x = realToFrac (c_ceil (realToFrac x))
{-# INLINE ceil #-}
foreign import ccall unsafe "math.h ceil"
c_ceil :: CDouble -> CDouble
fabs :: Double -> Double
fabs x = realToFrac (c_fabs (realToFrac x))
{-# INLINE fabs #-}
foreign import ccall unsafe "math.h fabs"
c_fabs :: CDouble -> CDouble
floor :: Double -> Double
floor x = realToFrac (c_floor (realToFrac x))
{-# INLINE floor #-}
foreign import ccall unsafe "math.h floor"
c_floor :: CDouble -> CDouble
fmod :: Double -> Double -> Double
fmod x y = realToFrac (c_fmod (realToFrac x) (realToFrac y))
{-# INLINE fmod #-}
foreign import ccall unsafe "math.h fmod"
c_fmod :: CDouble -> CDouble -> CDouble
round :: Double -> Double
round x = realToFrac (c_round (realToFrac x))
{-# INLINE round #-}
foreign import ccall unsafe "math.h round"
c_round :: CDouble -> CDouble
trunc :: Double -> Double
trunc x = realToFrac (c_trunc (realToFrac x))
{-# INLINE trunc #-}
foreign import ccall unsafe "math.h trunc"
c_trunc :: CDouble -> CDouble
erf :: Double -> Double
erf x = realToFrac (c_erf (realToFrac x))
{-# INLINE erf #-}
foreign import ccall unsafe "math.h erf"
c_erf :: CDouble -> CDouble
erfc :: Double -> Double
erfc x = realToFrac (c_erfc (realToFrac x))
{-# INLINE erfc #-}
foreign import ccall unsafe "math.h erfc"
c_erfc :: CDouble -> CDouble
gamma :: Double -> Double
gamma x = realToFrac (c_gamma (realToFrac x))
{-# INLINE gamma #-}
foreign import ccall unsafe "math.h gamma"
c_gamma :: CDouble -> CDouble
hypot :: Double -> Double -> Double
hypot x y = realToFrac (c_hypot (realToFrac x) (realToFrac y))
{-# INLINE hypot #-}
foreign import ccall unsafe "math.h hypot"
c_hypot :: CDouble -> CDouble -> CDouble
isinf :: Double -> Int
isinf x = fromIntegral (c_isinf (realToFrac x))
{-# INLINE isinf #-}
foreign import ccall unsafe "math.h isinf"
c_isinf :: CDouble -> CInt
isnan :: Double -> Int
isnan x = fromIntegral (c_isnan (realToFrac x))
{-# INLINE isnan #-}
foreign import ccall unsafe "math.h isnan"
c_isnan :: CDouble -> CInt
finite :: Double -> Int
finite x = fromIntegral (c_finite (realToFrac x))
{-# INLINE finite #-}
foreign import ccall unsafe "math.h finite"
c_finite :: CDouble -> CInt
j0 :: Double -> Double
j0 x = realToFrac (c_j0 (realToFrac x))
{-# INLINE j0 #-}
foreign import ccall unsafe "math.h j0"
c_j0 :: CDouble -> CDouble
j1 :: Double -> Double
j1 x = realToFrac (c_j1 (realToFrac x))
{-# INLINE j1 #-}
foreign import ccall unsafe "math.h j1"
c_j1 :: CDouble -> CDouble
y0 :: Double -> Double
y0 x = realToFrac (c_y0 (realToFrac x))
{-# INLINE y0 #-}
foreign import ccall unsafe "math.h y0"
c_y0 :: CDouble -> CDouble
y1 :: Double -> Double
y1 x = realToFrac (c_y1 (realToFrac x))
{-# INLINE y1 #-}
foreign import ccall unsafe "math.h y1"
c_y1 :: CDouble -> CDouble
yn :: Int -> Double -> Double
yn x y = realToFrac (c_yn (fromIntegral x) (realToFrac y))
{-# INLINE yn #-}
foreign import ccall unsafe "math.h yn"
c_yn :: CInt -> CDouble -> CDouble
lgamma :: Double -> Double
lgamma x = realToFrac (c_lgamma (realToFrac x))
{-# INLINE lgamma #-}
foreign import ccall unsafe "math.h lgamma"
c_lgamma :: CDouble -> CDouble
acosh :: Double -> Double
acosh x = realToFrac (c_acosh (realToFrac x))
{-# INLINE acosh #-}
foreign import ccall unsafe "math.h acosh"
c_acosh :: CDouble -> CDouble
asinh :: Double -> Double
asinh x = realToFrac (c_asinh (realToFrac x))
{-# INLINE asinh #-}
foreign import ccall unsafe "math.h asinh"
c_asinh :: CDouble -> CDouble
atanh :: Double -> Double
atanh x = realToFrac (c_atanh (realToFrac x))
{-# INLINE atanh #-}
foreign import ccall unsafe "math.h atanh"
c_atanh :: CDouble -> CDouble
cbrt :: Double -> Double
cbrt x = realToFrac (c_cbrt (realToFrac x))
{-# INLINE cbrt #-}
foreign import ccall unsafe "math.h cbrt"
c_cbrt :: CDouble -> CDouble
logb :: Double -> Double
logb x = realToFrac (c_logb (realToFrac x))
{-# INLINE logb #-}
foreign import ccall unsafe "math.h logb"
c_logb :: CDouble -> CDouble
nextafter :: Double -> Double -> Double
nextafter x y = realToFrac (c_nextafter (realToFrac x) (realToFrac y))
{-# INLINE nextafter #-}
foreign import ccall unsafe "math.h nextafter"
c_nextafter :: CDouble -> CDouble -> CDouble
remainder :: Double -> Double -> Double
remainder x y = realToFrac (c_remainder (realToFrac x) (realToFrac y))
{-# INLINE remainder #-}
foreign import ccall unsafe "math.h remainder"
c_remainder :: CDouble -> CDouble -> CDouble
scalb :: Double -> Double -> Double
scalb x y = realToFrac (c_scalb (realToFrac x) (realToFrac y))
{-# INLINE scalb #-}
foreign import ccall unsafe "math.h scalb"
c_scalb :: CDouble -> CDouble -> CDouble
significand :: Double -> Double
significand x = realToFrac (c_significand (realToFrac x))
{-# INLINE significand #-}
foreign import ccall unsafe "math.h significand"
c_significand :: CDouble -> CDouble
copysign :: Double -> Double -> Double
copysign x y = realToFrac (c_copysign (realToFrac x) (realToFrac y))
{-# INLINE copysign #-}
foreign import ccall unsafe "math.h copysign"
c_copysign :: CDouble -> CDouble -> CDouble
ilogb :: Double -> Int
ilogb x = fromIntegral (c_ilogb (realToFrac x))
{-# INLINE ilogb #-}
foreign import ccall unsafe "math.h ilogb"
c_ilogb :: CDouble -> CInt
rint :: Double -> Double
rint x = realToFrac (c_rint (realToFrac x))
{-# INLINE rint #-}
foreign import ccall unsafe "math.h rint"
c_rint :: CDouble -> CDouble
eq :: Double -> Double -> Bool
eq = (==) `on` doubleWord64
eqf :: Float -> Float -> Bool
eqf = (==) `on` floatWord32
maxNorm :: Double
maxNorm = shift (-1) maximal
maxNormf :: Float
maxNormf = shiftf (-1) maximal
minNorm :: Double
minNorm = word64Double 0x0080000000000000
minNormf :: Float
minNormf = word32Float 0x00800000
maxOdd :: Double
maxOdd = 9.007199254740991e15
maxOddf :: Float
maxOddf = 1.6777215e7
minSub :: Double
minSub = shift 1 0
minSubf :: Float
minSubf = shiftf 1 0
epsilon :: Double
epsilon = shift 1 1 - 1
epsilonf :: Float
epsilonf = shiftf 1 1 - 1
split :: Double -> Either Double Double
split x = case signBit x of
True -> Left x
_ -> Right x
splitf :: Float -> Either Float Float
splitf x = case signBitf x of
True -> Left x
_ -> Right x
shift :: Int64 -> Double -> Double
shift n = int64Double . (+ n) . doubleInt64
shiftf :: Int32 -> Float -> Float
shiftf n = int32Float . (+ n) . floatInt32
ulps :: Double -> Double -> (Bool, Word64)
ulps x y = o
where x' = doubleInt64 x
y' = doubleInt64 y
o | x' >= y' = (False, fromIntegral . abs $ x' - y')
| otherwise = (True, fromIntegral . abs $ y' - x')
ulpsf :: Float -> Float -> (Bool, Word32)
ulpsf x y = o
where x' = floatInt32 x
y' = floatInt32 y
o | x' >= y' = (False, fromIntegral . abs $ x' - y')
| otherwise = (True, fromIntegral . abs $ y' - x')
ulps' :: Double -> Double -> Word64
ulps' x y = snd $ ulps x y
ulpsf' :: Float -> Float -> Word32
ulpsf' x y = snd $ ulpsf x y
within :: Word64 -> Double -> Double -> Bool
within tol a b = ulps' a b <= tol
withinf :: Word32 -> Float -> Float -> Bool
withinf tol a b = ulpsf' a b <= tol
newtype Ulp32 = Ulp32 { unUlp32 :: Int32 } deriving Show
ulp32Nan :: Ulp32 -> Bool
ulp32Nan (Ulp32 x) = x /= (min 2139095040 . max (- 2139095041)) x
instance Eq Ulp32 where
x == y | ulp32Nan x && ulp32Nan y = True
| ulp32Nan x || ulp32Nan y = False
| otherwise = on (==) unUlp32 x y
instance Prd Ulp32 where
x <= y | ulp32Nan x && ulp32Nan y = True
| ulp32Nan x || ulp32Nan y = False
| otherwise = on (<=) unUlp32 x y
instance Minimal Ulp32 where
minimal = Ulp32 $ -2139095041
instance Maximal Ulp32 where
maximal = Ulp32 $ 2139095040
instance Semigroup (Additive Ulp32) where
Additive (Ulp32 x) <> Additive (Ulp32 y) = Additive . Ulp32 $ x + y
instance Monoid (Additive Ulp32) where
mempty = Additive $ Ulp32 0
instance Semigroup (Multiplicative Ulp32) where
Multiplicative (Ulp32 x) <> Multiplicative (Ulp32 y) = Multiplicative . Ulp32 $ x * y
instance Monoid (Multiplicative Ulp32) where
mempty = Multiplicative $ Ulp32 1
instance Presemiring Ulp32
instance Semiring Ulp32
instance Semigroup (Join Ulp32) where
Join (Ulp32 x) <> Join (Ulp32 y) = Join . Ulp32 $ P.max x y
instance Semigroup (Meet Ulp32) where
Meet (Ulp32 x) <> Meet (Ulp32 y) = Meet . Ulp32 $ P.min x y
f32u32 :: Conn Float Ulp32
f32u32 = Conn (Ulp32 . floatInt32) (int32Float . unUlp32)
u32f32 :: Conn Ulp32 Float
u32f32 = Conn (int32Float . unUlp32) (Ulp32 . floatInt32)
signBit :: Double -> Bool
signBit x = if x =~ anan then False else msbMask x /= 0
evenBit :: Double -> Bool
evenBit x = lsbMask x == 0
lsbMask :: Double -> Word64
lsbMask x = 0x0000000000000001 .&. doubleWord64 x
msbMask :: Double -> Word64
msbMask x = 0x8000000000000000 .&. doubleWord64 x
sigMask :: Double -> Word64
sigMask x = 0x007FFFFFFFFFFFFF .&. doubleWord64 x
signBitf :: Float -> Bool
signBitf x = if x =~ anan then False else msbMaskf x /= 0
evenBitf :: Float -> Bool
evenBitf x = lsbMaskf x == 0
lsbMaskf :: Float -> Word32
lsbMaskf x = 0x00000001 .&. floatWord32 x
msbMaskf :: Float -> Word32
msbMaskf x = 0x80000000 .&. floatWord32 x
expMaskf :: Float -> Word32
expMaskf x = 0x7f800000 .&. floatWord32 x
sigMaskf :: Float -> Word32
sigMaskf x = 0x007FFFFF .&. floatWord32 x
signed64 :: Word64 -> Int64
signed64 x | x < 0x8000000000000000 = fromIntegral x
| otherwise = fromIntegral (maximal P.- (x P.- 0x8000000000000000))
unsigned64 :: Int64 -> Word64
unsigned64 x | x >= 0 = fromIntegral x
| otherwise = 0x8000000000000000 + (maximal P.- (fromIntegral x))
int64Double :: Int64 -> Double
int64Double = word64Double . unsigned64
doubleInt64 :: Double -> Int64
doubleInt64 = signed64 . doubleWord64
word64Double :: Word64 -> Double
word64Double = F.castWord64ToDouble
doubleWord64 :: Double -> Word64
doubleWord64 = (+0) . F.castDoubleToWord64
signed32 :: Word32 -> Int32
signed32 x | x < 0x80000000 = fromIntegral x
| otherwise = fromIntegral (maximal P.- (x P.- 0x80000000))
unsigned32 :: Int32 -> Word32
unsigned32 x | x >= 0 = fromIntegral x
| otherwise = 0x80000000 + (maximal P.- (fromIntegral x))
int32Float :: Int32 -> Float
int32Float = word32Float . unsigned32
floatInt32 :: Float -> Int32
floatInt32 = signed32 . floatWord32
word32Float :: Word32 -> Float
word32Float = F.castWord32ToFloat
floatWord32 :: Float -> Word32
floatWord32 = (+0) . F.castFloatToWord32