hmpfr-0.4.2: src/Data/Number/MPFR/Instances/Zero.hs
{-# LANGUAGE MagicHash, CPP #-}
{-|
Module : Data.Number.MPFR.Instances.Zero
Description : Instance declarations
Copyright : (c) Aleš Bizjak
License : BSD3
Maintainer : mikkonecny@gmail.com
Stability : experimental
Portability : non-portable
This module defines instances 'Num', 'Real', 'Fractional', 'Floating' and 'RealFrac' of 'MPFR'.
Operations are rounded with 'RoundMode' 'Zero' and computed with maximum precision of two
operands or with the precision of the operand.
-}
module Data.Number.MPFR.Instances.Zero ()
where
import qualified Data.Number.MPFR.Arithmetic as A
import qualified Data.Number.MPFR.Special as S
import Data.Number.MPFR.Misc
import Data.Number.MPFR.Assignment
import Data.Number.MPFR.Comparison
import Data.Number.MPFR.Internal
import Data.Number.MPFR.Conversion
import Data.Number.MPFR.Integer
import Data.Maybe
import Data.Ratio
-- #ifdef INTEGER_SIMPLE
-- --import GHC.Integer.Simple.Internals
-- #endif
-- #ifdef INTEGER_GMP
-- import GHC.Integer.GMP.Internals
-- import qualified GHC.Exts as E
-- #endif
instance Num MPFR where
d + d' = A.add Zero (maxPrec d d') d d'
d - d' = A.sub Zero (maxPrec d d') d d'
d * d' = A.mul Zero (maxPrec d d') d d'
negate d = A.neg Zero (getPrec d) d
abs d = A.absD Zero (getPrec d) d
signum = fromInt Zero minPrec . fromMaybe (-1) . sgn
fromInteger i =
fromIntegerA Zero (max minPrec $ 1 + bitsInInteger i) i
-- #ifdef INTEGER_SIMPLE
-- fromInteger i =
-- fromIntegerA Zero (max minPrec $ 1 + bitsInInteger i) i
-- #endif
-- #ifdef INTEGER_GMP
-- fromInteger (S# i) = fromInt Zero minPrec (E.I# i)
-- fromInteger i@(J# n _) = fromIntegerA Zero (fromIntegral . abs $ E.I# n * bitsPerIntegerLimb) i
-- #endif
instance Real MPFR where
toRational d = n % 2 ^ e
where (n', e') = decompose d
(n, e) = if e' >= 0 then ((n' * 2 ^ e'), 0)
else (n', - e')
instance Fractional MPFR where
d / d' = A.div Zero (maxPrec d d') d d'
fromRational r = fromInteger n / fromInteger d
where n = numerator r
d = denominator r
recip d = one / d
instance Floating MPFR where
pi = S.pi Zero 53
exp d = S.exp Zero (getPrec d) d
log d = S.log Zero (getPrec d) d
sqrt d = A.sqrt Zero (getPrec d) d
(**) d d' = A.pow Zero (maxPrec d d') d d'
logBase d d' = Prelude.log d' / Prelude.log d
sin d = S.sin Zero (getPrec d) d
cos d = S.cos Zero (getPrec d) d
tan d = S.tan Zero (getPrec d) d
asin d = S.asin Zero (getPrec d) d
acos d = S.acos Zero (getPrec d) d
atan d = S.atan Zero (getPrec d) d
sinh d = S.sinh Zero (getPrec d) d
cosh d = S.cosh Zero (getPrec d) d
tanh d = S.tanh Zero (getPrec d) d
asinh d = S.asinh Zero (getPrec d) d
acosh d = S.acosh Zero (getPrec d) d
atanh d = S.atanh Zero (getPrec d) d
instance RealFrac MPFR where
properFraction d = (fromIntegral n, f)
where r = toRational d
m = numerator r
e = denominator r
n = quot m e
f = frac Zero (getPrec d) d
instance RealFloat MPFR where
floatRadix _ = 2
floatDigits = fromInteger . toInteger . getPrec
floatRange _ = error "floatRange is not defined for MPFR numbers"
decodeFloat x = (d,e)
where
(d,eE) = decompose x
e = fromInteger (toInteger eE)
encodeFloat d e =
(fromInteger d) / ((fromInteger 2)^e) -- TODO: construct it directly
isNaN (MP _ _ e _) = (e == expNaN)
isInfinite (MP _ _ e _) = (e == expInf)
isDenormalized _ = False
isNegativeZero d@(MP _ _ e _) = (e == expZero && signbit d)
isIEEE _ = False
atan2 d1 d2 = S.atan2 Near (maxPrec d1 d2) d1 d2