{-# Language BangPatterns #-}
{-# Language BlockArguments #-}
{-# Language Trustworthy #-}
module LibBF
(
BigFloat
, bfPosZero, bfNegZero
, bfPosInf, bfNegInf
, bfNaN
, bfFromWord
, bfFromInt
, bfFromDouble
, bfFromInteger
, bfFromString
, bfToDouble
, bfToString
, bfToRep
, BFRep(..)
, BFNum(..)
, bfFromBits
, bfToBits
, bfIsFinite
, bfIsInf
, bfIsZero
, bfIsNaN
, bfIsNormal
, bfIsSubnormal
, bfCompare
, bfSign
, bfExponent
, bfIsPos
, bfIsNeg
, Sign(..)
, bfNeg, bfAbs
, bfAdd, bfSub, bfMul, bfDiv, bfRem
, bfFMA, bfMulWord, bfMulInt, bfMul2Exp
, bfSqrt
, bfPow
, bfRoundFloat, bfRoundInt
, bfUnsafeThaw
, bfUnsafeFreeze
, module LibBF.Opts
) where
import Data.Bits
import Data.Hashable
import Data.Word
import Data.Int
import System.IO.Unsafe
import LibBF.Mutable as M
import LibBF.Opts
import Control.DeepSeq
newtype BigFloat = BigFloat BF
instance NFData BigFloat where
rnf :: BigFloat -> ()
rnf BigFloat
x = BigFloat
x seq :: forall a b. a -> b -> b
`seq` ()
instance Show BigFloat where
show :: BigFloat -> String
show = Int -> ShowFmt -> BigFloat -> String
bfToString Int
16 (Maybe Word -> ShowFmt
showFreeMin forall a. Maybe a
Nothing forall a. Semigroup a => a -> a -> a
<> ShowFmt
addPrefix)
{-# NOINLINE ctxt #-}
{-# OPTIONS_GHC -fno-cse #-}
ctxt :: BFContext
ctxt :: BFContext
ctxt = forall a. IO a -> a
unsafePerformIO IO BFContext
newContext
newBigFloat :: (BF -> IO ()) -> BigFloat
newBigFloat :: (BF -> IO ()) -> BigFloat
newBigFloat BF -> IO ()
f = forall a. IO a -> a
unsafe forall a b. (a -> b) -> a -> b
$
do BF
bf <- BFContext -> IO BF
new BFContext
ctxt
BF -> IO ()
f BF
bf
forall (f :: * -> *) a. Applicative f => a -> f a
pure (BF -> BigFloat
BigFloat BF
bf)
newBigFloat' :: (BF -> IO a) -> (BigFloat,a)
newBigFloat' :: forall a. (BF -> IO a) -> (BigFloat, a)
newBigFloat' BF -> IO a
f = forall a. IO a -> a
unsafe forall a b. (a -> b) -> a -> b
$
do BF
bf <- BFContext -> IO BF
new BFContext
ctxt
a
a <- BF -> IO a
f BF
bf
forall (f :: * -> *) a. Applicative f => a -> f a
pure (BF -> BigFloat
BigFloat BF
bf, a
a)
unsafe :: IO a -> a
unsafe :: forall a. IO a -> a
unsafe = forall a. IO a -> a
unsafePerformIO
bfPosZero :: BigFloat
bfPosZero :: BigFloat
bfPosZero = (BF -> IO ()) -> BigFloat
newBigFloat (Sign -> BF -> IO ()
setZero Sign
Pos)
bfNegZero :: BigFloat
bfNegZero :: BigFloat
bfNegZero = (BF -> IO ()) -> BigFloat
newBigFloat (Sign -> BF -> IO ()
setZero Sign
Neg)
bfPosInf :: BigFloat
bfPosInf :: BigFloat
bfPosInf = (BF -> IO ()) -> BigFloat
newBigFloat (Sign -> BF -> IO ()
setInf Sign
Pos)
bfNegInf :: BigFloat
bfNegInf :: BigFloat
bfNegInf = (BF -> IO ()) -> BigFloat
newBigFloat (Sign -> BF -> IO ()
setInf Sign
Neg)
bfNaN :: BigFloat
bfNaN :: BigFloat
bfNaN = (BF -> IO ()) -> BigFloat
newBigFloat BF -> IO ()
setNaN
bfFromWord :: Word64 -> BigFloat
bfFromWord :: Word64 -> BigFloat
bfFromWord = (BF -> IO ()) -> BigFloat
newBigFloat forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> BF -> IO ()
setWord
bfFromInt :: Int64 -> BigFloat
bfFromInt :: Int64 -> BigFloat
bfFromInt = (BF -> IO ()) -> BigFloat
newBigFloat forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> BF -> IO ()
setInt
bfFromDouble :: Double -> BigFloat
bfFromDouble :: Double -> BigFloat
bfFromDouble = (BF -> IO ()) -> BigFloat
newBigFloat forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> BF -> IO ()
setDouble
bfFromInteger :: Integer -> BigFloat
bfFromInteger :: Integer -> BigFloat
bfFromInteger = (BF -> IO ()) -> BigFloat
newBigFloat forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> BF -> IO ()
setInteger
instance Eq BigFloat where
BigFloat BF
x == :: BigFloat -> BigFloat -> Bool
== BigFloat BF
y = forall a. IO a -> a
unsafe (BF -> BF -> IO Bool
cmpEq BF
x BF
y)
instance Ord BigFloat where
BigFloat BF
x < :: BigFloat -> BigFloat -> Bool
< BigFloat BF
y = forall a. IO a -> a
unsafe (BF -> BF -> IO Bool
cmpLT BF
x BF
y)
BigFloat BF
x <= :: BigFloat -> BigFloat -> Bool
<= BigFloat BF
y = forall a. IO a -> a
unsafe (BF -> BF -> IO Bool
cmpLEQ BF
x BF
y)
instance Hashable BigFloat where
hashWithSalt :: Int -> BigFloat -> Int
hashWithSalt Int
s BigFloat
x = forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
s (BigFloat -> BFRep
bfToRep BigFloat
x)
bfCompare :: BigFloat -> BigFloat -> Ordering
bfCompare :: BigFloat -> BigFloat -> Ordering
bfCompare (BigFloat BF
x) (BigFloat BF
y) = forall a. IO a -> a
unsafe (BF -> BF -> IO Ordering
cmp BF
x BF
y)
bfIsFinite :: BigFloat -> Bool
bfIsFinite :: BigFloat -> Bool
bfIsFinite (BigFloat BF
x) = forall a. IO a -> a
unsafe (BF -> IO Bool
isFinite BF
x)
bfIsNaN :: BigFloat -> Bool
bfIsNaN :: BigFloat -> Bool
bfIsNaN (BigFloat BF
x) = forall a. IO a -> a
unsafe (BF -> IO Bool
M.isNaN BF
x)
bfIsInf :: BigFloat -> Bool
bfIsInf :: BigFloat -> Bool
bfIsInf (BigFloat BF
x) = forall a. IO a -> a
unsafe (BF -> IO Bool
isInf BF
x)
bfIsNormal :: BFOpts -> BigFloat -> Bool
bfIsNormal :: BFOpts -> BigFloat -> Bool
bfIsNormal BFOpts
opts BigFloat
bf =
case BigFloat -> BFRep
bfToRep BigFloat
bf of
rep :: BFRep
rep@(BFRep Sign
_sgn (Num Integer
_ Int64
_)) -> Bool -> Bool
not (BFOpts -> BFRep -> Bool
repIsSubnormal BFOpts
opts BFRep
rep)
BFRep
_ -> Bool
False
bfIsSubnormal :: BFOpts -> BigFloat -> Bool
bfIsSubnormal :: BFOpts -> BigFloat -> Bool
bfIsSubnormal BFOpts
opts BigFloat
bf = BFOpts -> BFRep -> Bool
repIsSubnormal BFOpts
opts (BigFloat -> BFRep
bfToRep BigFloat
bf)
bfSign :: BigFloat -> Maybe Sign
bfSign :: BigFloat -> Maybe Sign
bfSign (BigFloat BF
x) = forall a. IO a -> a
unsafe (BF -> IO (Maybe Sign)
getSign BF
x)
bfAbs :: BigFloat -> BigFloat
bfAbs :: BigFloat -> BigFloat
bfAbs BigFloat
bf =
case BigFloat -> Maybe Sign
bfSign BigFloat
bf of
Just Sign
Neg -> BigFloat -> BigFloat
bfNeg BigFloat
bf
Maybe Sign
_ -> BigFloat
bf
bfIsPos :: BigFloat -> Bool
bfIsPos :: BigFloat -> Bool
bfIsPos BigFloat
bf =
case BigFloat -> Maybe Sign
bfSign BigFloat
bf of
Just Sign
Pos -> Bool
True
Maybe Sign
_ -> Bool
False
bfIsNeg :: BigFloat -> Bool
bfIsNeg :: BigFloat -> Bool
bfIsNeg BigFloat
bf =
case BigFloat -> Maybe Sign
bfSign BigFloat
bf of
Just Sign
Neg -> Bool
True
Maybe Sign
_ -> Bool
False
bfExponent :: BigFloat -> Maybe Int64
bfExponent :: BigFloat -> Maybe Int64
bfExponent (BigFloat BF
x) = forall a. IO a -> a
unsafe (BF -> IO (Maybe Int64)
getExp BF
x)
bfIsZero :: BigFloat -> Bool
bfIsZero :: BigFloat -> Bool
bfIsZero (BigFloat BF
x) = forall a. IO a -> a
unsafe (BF -> IO Bool
isZero BF
x)
bfNeg :: BigFloat -> BigFloat
bfNeg :: BigFloat -> BigFloat
bfNeg (BigFloat BF
x) = (BF -> IO ()) -> BigFloat
newBigFloat (\BF
bf -> BF -> BF -> IO ()
setBF BF
x BF
bf forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> BF -> IO ()
fneg BF
bf)
bfAdd :: BFOpts -> BigFloat -> BigFloat -> (BigFloat,Status)
bfAdd :: BFOpts -> BigFloat -> BigFloat -> (BigFloat, Status)
bfAdd BFOpts
opt (BigFloat BF
x) (BigFloat BF
y) = forall a. (BF -> IO a) -> (BigFloat, a)
newBigFloat' (BFOpts -> BF -> BF -> BF -> IO Status
fadd BFOpts
opt BF
x BF
y)
bfSub :: BFOpts -> BigFloat -> BigFloat -> (BigFloat,Status)
bfSub :: BFOpts -> BigFloat -> BigFloat -> (BigFloat, Status)
bfSub BFOpts
opt (BigFloat BF
x) (BigFloat BF
y) = forall a. (BF -> IO a) -> (BigFloat, a)
newBigFloat' (BFOpts -> BF -> BF -> BF -> IO Status
fsub BFOpts
opt BF
x BF
y)
bfMul :: BFOpts -> BigFloat -> BigFloat -> (BigFloat,Status)
bfMul :: BFOpts -> BigFloat -> BigFloat -> (BigFloat, Status)
bfMul BFOpts
opt (BigFloat BF
x) (BigFloat BF
y) = forall a. (BF -> IO a) -> (BigFloat, a)
newBigFloat' (BFOpts -> BF -> BF -> BF -> IO Status
fmul BFOpts
opt BF
x BF
y)
bfMulWord :: BFOpts -> BigFloat -> Word64 -> (BigFloat,Status)
bfMulWord :: BFOpts -> BigFloat -> Word64 -> (BigFloat, Status)
bfMulWord BFOpts
opt (BigFloat BF
x) Word64
y = forall a. (BF -> IO a) -> (BigFloat, a)
newBigFloat' (BFOpts -> BF -> Word64 -> BF -> IO Status
fmulWord BFOpts
opt BF
x Word64
y)
bfMulInt :: BFOpts -> BigFloat -> Int64 -> (BigFloat,Status)
bfMulInt :: BFOpts -> BigFloat -> Int64 -> (BigFloat, Status)
bfMulInt BFOpts
opt (BigFloat BF
x) Int64
y = forall a. (BF -> IO a) -> (BigFloat, a)
newBigFloat' (BFOpts -> BF -> Int64 -> BF -> IO Status
fmulInt BFOpts
opt BF
x Int64
y)
bfMul2Exp :: BFOpts -> BigFloat -> Int -> (BigFloat,Status)
bfMul2Exp :: BFOpts -> BigFloat -> Int -> (BigFloat, Status)
bfMul2Exp BFOpts
opt (BigFloat BF
x) Int
e = forall a. (BF -> IO a) -> (BigFloat, a)
newBigFloat' (\BF
p ->
do BF -> BF -> IO ()
setBF BF
x BF
p
BFOpts -> Int -> BF -> IO Status
fmul2Exp BFOpts
opt Int
e BF
p)
bfDiv :: BFOpts -> BigFloat -> BigFloat -> (BigFloat,Status)
bfDiv :: BFOpts -> BigFloat -> BigFloat -> (BigFloat, Status)
bfDiv BFOpts
opt (BigFloat BF
x) (BigFloat BF
y) = forall a. (BF -> IO a) -> (BigFloat, a)
newBigFloat' (BFOpts -> BF -> BF -> BF -> IO Status
fdiv BFOpts
opt BF
x BF
y)
bfRem :: BFOpts -> BigFloat -> BigFloat -> (BigFloat, Status)
bfRem :: BFOpts -> BigFloat -> BigFloat -> (BigFloat, Status)
bfRem BFOpts
opt (BigFloat BF
x) (BigFloat BF
y) = forall a. (BF -> IO a) -> (BigFloat, a)
newBigFloat' (BFOpts -> BF -> BF -> BF -> IO Status
frem BFOpts
opt BF
x BF
y)
bfFMA :: BFOpts -> BigFloat -> BigFloat -> BigFloat -> (BigFloat, Status)
bfFMA :: BFOpts -> BigFloat -> BigFloat -> BigFloat -> (BigFloat, Status)
bfFMA BFOpts
opt (BigFloat BF
x) (BigFloat BF
y) (BigFloat BF
z) = forall a. (BF -> IO a) -> (BigFloat, a)
newBigFloat' (BFOpts -> BF -> BF -> BF -> BF -> IO Status
ffma BFOpts
opt BF
x BF
y BF
z)
bfSqrt :: BFOpts -> BigFloat -> (BigFloat,Status)
bfSqrt :: BFOpts -> BigFloat -> (BigFloat, Status)
bfSqrt BFOpts
opt (BigFloat BF
x) = forall a. (BF -> IO a) -> (BigFloat, a)
newBigFloat' (BFOpts -> BF -> BF -> IO Status
fsqrt BFOpts
opt BF
x)
bfRoundFloat :: BFOpts -> BigFloat -> (BigFloat,Status)
bfRoundFloat :: BFOpts -> BigFloat -> (BigFloat, Status)
bfRoundFloat BFOpts
opt (BigFloat BF
x) = forall a. (BF -> IO a) -> (BigFloat, a)
newBigFloat' (\BF
bf ->
do BF -> BF -> IO ()
setBF BF
x BF
bf
BFOpts -> BF -> IO Status
fround BFOpts
opt BF
bf
)
bfRoundInt :: RoundMode -> BigFloat -> (BigFloat,Status)
bfRoundInt :: RoundMode -> BigFloat -> (BigFloat, Status)
bfRoundInt RoundMode
r (BigFloat BF
x) = forall a. (BF -> IO a) -> (BigFloat, a)
newBigFloat' (\BF
bf ->
do BF -> BF -> IO ()
setBF BF
x BF
bf
RoundMode -> BF -> IO Status
frint RoundMode
r BF
bf
)
bfPow :: BFOpts -> BigFloat -> BigFloat -> (BigFloat, Status)
bfPow :: BFOpts -> BigFloat -> BigFloat -> (BigFloat, Status)
bfPow BFOpts
opts (BigFloat BF
x) (BigFloat BF
y) = forall a. (BF -> IO a) -> (BigFloat, a)
newBigFloat' (BFOpts -> BF -> BF -> BF -> IO Status
fpow BFOpts
opts BF
x BF
y)
bfToDouble :: RoundMode -> BigFloat -> (Double, Status)
bfToDouble :: RoundMode -> BigFloat -> (Double, Status)
bfToDouble RoundMode
r (BigFloat BF
x) = forall a. IO a -> a
unsafe (RoundMode -> BF -> IO (Double, Status)
toDouble RoundMode
r BF
x)
bfToString :: Int -> ShowFmt -> BigFloat -> String
bfToString :: Int -> ShowFmt -> BigFloat -> String
bfToString Int
radix ShowFmt
opts (BigFloat BF
x) =
forall a. IO a -> a
unsafe (Int -> ShowFmt -> BF -> IO String
toString Int
radix ShowFmt
opts BF
x)
bfFromString :: Int -> BFOpts -> String -> (BigFloat,Status)
bfFromString :: Int -> BFOpts -> String -> (BigFloat, Status)
bfFromString Int
radix BFOpts
opts String
str =
forall a. (BF -> IO a) -> (BigFloat, a)
newBigFloat' \BF
bf ->
do (Status
status,Int
_,Bool
usedAll) <- Int -> BFOpts -> String -> BF -> IO (Status, Int, Bool)
setString Int
radix BFOpts
opts String
str BF
bf
if Bool
usedAll
then forall (f :: * -> *) a. Applicative f => a -> f a
pure Status
status
else do BF -> IO ()
setNaN BF
bf
forall (f :: * -> *) a. Applicative f => a -> f a
pure Status
Ok
bfToRep :: BigFloat -> BFRep
bfToRep :: BigFloat -> BFRep
bfToRep (BigFloat BF
x) = forall a. IO a -> a
unsafe (BF -> IO BFRep
toRep BF
x)
bfUnsafeThaw :: BigFloat -> BF
bfUnsafeThaw :: BigFloat -> BF
bfUnsafeThaw (BigFloat BF
x) = BF
x
bfUnsafeFreeze :: BF -> BigFloat
bfUnsafeFreeze :: BF -> BigFloat
bfUnsafeFreeze = BF -> BigFloat
BigFloat
bfFromBits ::
BFOpts ->
Integer ->
BigFloat
bfFromBits :: BFOpts -> Integer -> BigFloat
bfFromBits BFOpts
opts Integer
bits
| Int
expoBiased forall a. Eq a => a -> a -> Bool
== Int
0 Bool -> Bool -> Bool
&& Integer
mant forall a. Eq a => a -> a -> Bool
== Integer
0 =
if Bool
isNeg then BigFloat
bfNegZero else BigFloat
bfPosZero
| Int
expoBiased forall a. Eq a => a -> a -> Bool
== Int
eMask Bool -> Bool -> Bool
&& Integer
mant forall a. Eq a => a -> a -> Bool
== Integer
0 =
if Bool
isNeg then BigFloat
bfNegInf else BigFloat
bfPosInf
| Int
expoBiased forall a. Eq a => a -> a -> Bool
== Int
eMask = BigFloat
bfNaN
| Int
expoBiased forall a. Eq a => a -> a -> Bool
== Int
0 =
case BFOpts -> BigFloat -> Int -> (BigFloat, Status)
bfMul2Exp BFOpts
opts' (Integer -> BigFloat
bfFromInteger Integer
mant) (Int
expoVal forall a. Num a => a -> a -> a
+ Int
1) of
(BigFloat
num,Status
Ok) -> if Bool
isNeg then BigFloat -> BigFloat
bfNeg BigFloat
num else BigFloat
num
(BigFloat
_,Status
s) -> forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ [String] -> String
unwords [String
"bfFromBits", String
"subnormal case", String
"Unexpected status:", forall a. Show a => a -> String
show Status
s, forall a. Show a => a -> String
show Integer
bits, forall a. Show a => a -> String
show Integer
mant, forall a. Show a => a -> String
show Int
expoVal, forall a. Show a => a -> String
show Int
e, forall a. Show a => a -> String
show Word
p ]
| Bool
otherwise =
case BFOpts -> BigFloat -> Int -> (BigFloat, Status)
bfMul2Exp BFOpts
opts' (Integer -> BigFloat
bfFromInteger Integer
mantVal) Int
expoVal of
(BigFloat
num,Status
Ok) -> if Bool
isNeg then BigFloat -> BigFloat
bfNeg BigFloat
num else BigFloat
num
(BigFloat
_,Status
s) -> forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ [String] -> String
unwords [String
"bfFromBits", String
"normal case", String
"Unexpected status:", forall a. Show a => a -> String
show Status
s, forall a. Show a => a -> String
show Integer
bits, forall a. Show a => a -> String
show Integer
mantVal, forall a. Show a => a -> String
show Int
expoVal, forall a. Show a => a -> String
show Int
e, forall a. Show a => a -> String
show Word
p ]
where
e :: Int
e = BFOpts -> Int
getExpBits BFOpts
opts
p :: Word
p = BFOpts -> Word
getPrecBits BFOpts
opts
opts' :: BFOpts
opts' = BFOpts
opts forall a. Semigroup a => a -> a -> a
<> BFOpts
allowSubnormal
p' :: Int
p' = forall a b. (Integral a, Num b) => a -> b
fromIntegral Word
p forall a. Num a => a -> a -> a
- Int
1 :: Int
eMask :: Int
eMask = (Int
1 forall a. Bits a => a -> Int -> a
`shiftL` Int
e) forall a. Num a => a -> a -> a
- Int
1 :: Int
pMask :: Integer
pMask = (Integer
1 forall a. Bits a => a -> Int -> a
`shiftL` Int
p') forall a. Num a => a -> a -> a
- Integer
1 :: Integer
isNeg :: Bool
isNeg = forall a. Bits a => a -> Int -> Bool
testBit Integer
bits (Int
e forall a. Num a => a -> a -> a
+ Int
p')
mant :: Integer
mant = Integer
pMask forall a. Bits a => a -> a -> a
.&. Integer
bits :: Integer
mantVal :: Integer
mantVal = Integer
mant forall a. Bits a => a -> Int -> a
`setBit` Int
p' :: Integer
expoBiased :: Int
expoBiased = Int
eMask forall a. Bits a => a -> a -> a
.&. forall a. Num a => Integer -> a
fromInteger (Integer
bits forall a. Bits a => a -> Int -> a
`shiftR` Int
p') :: Int
bias :: Int
bias = Int
eMask forall a. Bits a => a -> Int -> a
`shiftR` Int
1 :: Int
expoVal :: Int
expoVal = Int
expoBiased forall a. Num a => a -> a -> a
- Int
bias forall a. Num a => a -> a -> a
- forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
p' :: Int
bfToBits :: BFOpts -> BigFloat -> Integer
bfToBits :: BFOpts -> BigFloat -> Integer
bfToBits BFOpts
opts BigFloat
bf = Integer
res
where
res :: Integer
res = (Integer
isNeg forall a. Bits a => a -> Int -> a
`shiftL` (Int
eforall a. Num a => a -> a -> a
+Int
p'))
forall a. Bits a => a -> a -> a
.|. (Integer
expBiased forall a. Bits a => a -> Int -> a
`shiftL` Int
p')
forall a. Bits a => a -> a -> a
.|. (Integer
mant forall a. Bits a => a -> Int -> a
`shiftL` Int
0)
e :: Int
e = BFOpts -> Int
getExpBits BFOpts
opts
p :: Word
p = BFOpts -> Word
getPrecBits BFOpts
opts
p' :: Int
p' = forall a b. (Integral a, Num b) => a -> b
fromIntegral Word
p forall a. Num a => a -> a -> a
- Int
1 :: Int
eMask :: Integer
eMask = (Integer
1 forall a. Bits a => a -> Int -> a
`shiftL` Int
e) forall a. Num a => a -> a -> a
- Integer
1 :: Integer
pMask :: Integer
pMask = (Integer
1 forall a. Bits a => a -> Int -> a
`shiftL` Int
p') forall a. Num a => a -> a -> a
- Integer
1 :: Integer
(Integer
isNeg, Integer
expBiased, Integer
mant) =
case BigFloat -> BFRep
bfToRep BigFloat
bf of
BFRep
BFNaN -> (Integer
0, Integer
eMask, Integer
1 forall a. Bits a => a -> Int -> a
`shiftL` (Int
p' forall a. Num a => a -> a -> a
- Int
1))
BFRep Sign
s BFNum
num -> (Integer
sign, Integer
be, Integer
ma)
where
sign :: Integer
sign = case Sign
s of
Sign
Neg -> Integer
1
Sign
Pos -> Integer
0
(Integer
be,Integer
ma) =
case BFNum
num of
BFNum
Zero -> (Integer
0,Integer
0)
Num Integer
i Int64
ev
| Integer
ex forall a. Ord a => a -> a -> Bool
<= Integer
0 ->
(Integer
0, Integer
i forall a. Bits a => a -> Int -> a
`shiftL` (Int
p'forall a. Num a => a -> a -> a
-Int
mforall a. Num a => a -> a -> a
-Int
1forall a. Num a => a -> a -> a
+forall a. Num a => Integer -> a
fromInteger Integer
ex))
| Bool
otherwise ->
(Integer
ex, (Integer
i forall a. Bits a => a -> Int -> a
`shiftL` (Int
p' forall a. Num a => a -> a -> a
- Int
m)) forall a. Bits a => a -> a -> a
.&. Integer
pMask)
where
m :: Int
m = forall {t} {t}. (Num t, Num t, Bits t) => t -> t -> t
msb Int
0 Integer
i forall a. Num a => a -> a -> a
- Int
1
bias :: Integer
bias = Integer
eMask forall a. Bits a => a -> Int -> a
`shiftR` Int
1
ex :: Integer
ex = forall a. Integral a => a -> Integer
toInteger Int64
ev forall a. Num a => a -> a -> a
+ Integer
bias forall a. Num a => a -> a -> a
+ forall a. Integral a => a -> Integer
toInteger Int
m
BFNum
Inf -> (Integer
eMask,Integer
0)
msb :: t -> t -> t
msb !t
n t
j = if t
j forall a. Eq a => a -> a -> Bool
== t
0 then t
n else t -> t -> t
msb (t
nforall a. Num a => a -> a -> a
+t
1) (t
j forall a. Bits a => a -> Int -> a
`shiftR` Int
1)
repIsSubnormal :: BFOpts -> BFRep -> Bool
repIsSubnormal :: BFOpts -> BFRep -> Bool
repIsSubnormal BFOpts
opts (BFRep Sign
_s (Num Integer
i Int64
ev)) = Integer
ex forall a. Ord a => a -> a -> Bool
<= Integer
0
where
e :: Int
e = BFOpts -> Int
getExpBits BFOpts
opts
eMask :: Integer
eMask = (Integer
1 forall a. Bits a => a -> Int -> a
`shiftL` Int
e) forall a. Num a => a -> a -> a
- Integer
1 :: Integer
bias :: Integer
bias = Integer
eMask forall a. Bits a => a -> Int -> a
`shiftR` Int
1
m :: Int
m = forall {t} {t}. (Num t, Num t, Bits t) => t -> t -> t
msb (Int
0 :: Int) Integer
i forall a. Num a => a -> a -> a
- Int
1
ex :: Integer
ex = forall a. Integral a => a -> Integer
toInteger Int64
ev forall a. Num a => a -> a -> a
+ Integer
bias forall a. Num a => a -> a -> a
+ forall a. Integral a => a -> Integer
toInteger Int
m
msb :: t -> t -> t
msb !t
n t
j = if t
j forall a. Eq a => a -> a -> Bool
== t
0 then t
n else t -> t -> t
msb (t
nforall a. Num a => a -> a -> a
+t
1) (t
j forall a. Bits a => a -> Int -> a
`shiftR` Int
1)
repIsSubnormal BFOpts
_opts BFRep
_rep = Bool
False