Content-Length: 337996 | pFad | http://hackage.haskell.org/package/libBF-0.6.8/docs/src/LibBF.html#bfFromInteger
{-# Language BangPatterns #-} {-# Language BlockArguments #-} {-# Language Trustworthy #-} -- | Computation with high-precision floats. module LibBF ( -- * Constants BigFloat , bfPosZero, bfNegZero , bfPosInf, bfNegInf , bfNaN -- * Conversions , bfFromWord , bfFromInt , bfFromDouble , bfFromInteger , bfFromString , bfToDouble , bfToString , bfToRep , BFRep(..) , BFNum(..) , bfFromBits , bfToBits -- * Predicates , bfIsFinite , bfIsInf , bfIsZero , bfIsNaN , bfIsNormal , bfIsSubnormal , bfCompare , bfSign , bfExponent , bfIsPos , bfIsNeg , Sign(..) -- * Arithmetic , bfNeg, bfAbs , bfAdd, bfSub, bfMul, bfDiv, bfRem , bfFMA, bfMulWord, bfMulInt, bfMul2Exp , bfSqrt , bfPow -- * Rounding , bfRoundFloat, bfRoundInt -- * Mutability , bfUnsafeThaw , bfUnsafeFreeze -- * Limits -- * Configuration , module LibBF.Opts ) where import Data.Bits import Data.Data (Data(..)) import Data.Hashable import Data.Word import Data.Int import System.IO.Unsafe import LibBF.Mutable as M import LibBF.Opts import Control.DeepSeq -- | Arbitrary precision floating point numbers. newtype BigFloat = BigFloat BF instance Data BigFloat where -- BigFloat is exported as an abstract data type, so we intentionally define -- the Data instance in a simplistic way so as to avoid leaking the BF -- internals. gfoldl :: forall (c :: * -> *). (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> BigFloat -> c BigFloat gfoldl forall d b. Data d => c (d -> b) -> d -> c b _ forall g. g -> c g z = BigFloat -> c BigFloat forall g. g -> c g z gunfold :: forall (c :: * -> *). (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c BigFloat gunfold forall b r. Data b => c (b -> r) -> c r _ forall r. r -> c r _ = [Char] -> Constr -> c BigFloat forall a. HasCallStack => [Char] -> a error [Char] "Data.Data.gunfold(BigFloat)" toConstr :: BigFloat -> Constr toConstr BigFloat _ = [Char] -> Constr forall a. HasCallStack => [Char] -> a error [Char] "Data.Data.toConstr(BigFloat)" dataTypeOf :: BigFloat -> DataType dataTypeOf BigFloat _ = [Char] -> DataType forall a. HasCallStack => [Char] -> a error [Char] "Data.Data.dataTypeOf(BigFloat)" instance NFData BigFloat where rnf :: BigFloat -> () rnf BigFloat x = BigFloat x BigFloat -> () -> () forall a b. a -> b -> b `seq` () instance Show BigFloat where show :: BigFloat -> [Char] show = Int -> ShowFmt -> BigFloat -> [Char] bfToString Int 16 (Maybe Word -> ShowFmt showFreeMin Maybe Word forall a. Maybe a Nothing ShowFmt -> ShowFmt -> ShowFmt forall a. Semigroup a => a -> a -> a <> ShowFmt addPrefix) -------------------------------------------------------------------------------- {-# NOINLINE ctxt #-} {-# OPTIONS_GHC -fno-cse #-} ctxt :: BFContext ctxt :: BFContext ctxt = IO BFContext -> BFContext forall a. IO a -> a unsafePerformIO IO BFContext newContext newBigFloat :: (BF -> IO ()) -> BigFloat newBigFloat :: (BF -> IO ()) -> BigFloat newBigFloat BF -> IO () f = IO BigFloat -> BigFloat forall a. IO a -> a unsafe (IO BigFloat -> BigFloat) -> IO BigFloat -> BigFloat forall a b. (a -> b) -> a -> b $ do BF bf <- BFContext -> IO BF new BFContext ctxt BF -> IO () f BF bf BigFloat -> IO BigFloat forall a. a -> IO a 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 = IO (BigFloat, a) -> (BigFloat, a) forall a. IO a -> a unsafe (IO (BigFloat, a) -> (BigFloat, a)) -> IO (BigFloat, a) -> (BigFloat, a) forall a b. (a -> b) -> a -> b $ do BF bf <- BFContext -> IO BF new BFContext ctxt a a <- BF -> IO a f BF bf (BigFloat, a) -> IO (BigFloat, a) forall a. a -> IO a 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 = IO a -> a forall a. IO a -> a unsafePerformIO -------------------------------------------------------------------------------- -- Constants -- | Positive zero. bfPosZero :: BigFloat bfPosZero :: BigFloat bfPosZero = (BF -> IO ()) -> BigFloat newBigFloat (Sign -> BF -> IO () setZero Sign Pos) -- | Negative zero. bfNegZero :: BigFloat bfNegZero :: BigFloat bfNegZero = (BF -> IO ()) -> BigFloat newBigFloat (Sign -> BF -> IO () setZero Sign Neg) -- | Positive infinity. bfPosInf :: BigFloat bfPosInf :: BigFloat bfPosInf = (BF -> IO ()) -> BigFloat newBigFloat (Sign -> BF -> IO () setInf Sign Pos) -- | Negative infinity. bfNegInf :: BigFloat bfNegInf :: BigFloat bfNegInf = (BF -> IO ()) -> BigFloat newBigFloat (Sign -> BF -> IO () setInf Sign Neg) -- | Not-a-number. bfNaN :: BigFloat bfNaN :: BigFloat bfNaN = (BF -> IO ()) -> BigFloat newBigFloat BF -> IO () setNaN -- | A floating point number corresponding to the given word. bfFromWord :: Word64 -> BigFloat bfFromWord :: Word64 -> BigFloat bfFromWord = (BF -> IO ()) -> BigFloat newBigFloat ((BF -> IO ()) -> BigFloat) -> (Word64 -> BF -> IO ()) -> Word64 -> BigFloat forall b c a. (b -> c) -> (a -> b) -> a -> c . Word64 -> BF -> IO () setWord -- | A floating point number corresponding to the given int. bfFromInt :: Int64 -> BigFloat bfFromInt :: Int64 -> BigFloat bfFromInt = (BF -> IO ()) -> BigFloat newBigFloat ((BF -> IO ()) -> BigFloat) -> (Int64 -> BF -> IO ()) -> Int64 -> BigFloat forall b c a. (b -> c) -> (a -> b) -> a -> c . Int64 -> BF -> IO () setInt -- | A floating point number corresponding to the given double. bfFromDouble :: Double -> BigFloat bfFromDouble :: Double -> BigFloat bfFromDouble = (BF -> IO ()) -> BigFloat newBigFloat ((BF -> IO ()) -> BigFloat) -> (Double -> BF -> IO ()) -> Double -> BigFloat forall b c a. (b -> c) -> (a -> b) -> a -> c . Double -> BF -> IO () setDouble -- | A floating point number corresponding to the given integer. bfFromInteger :: Integer -> BigFloat bfFromInteger :: Integer -> BigFloat bfFromInteger = (BF -> IO ()) -> BigFloat newBigFloat ((BF -> IO ()) -> BigFloat) -> (Integer -> BF -> IO ()) -> Integer -> BigFloat forall b c a. (b -> c) -> (a -> b) -> a -> c . Integer -> BF -> IO () setInteger -- | IEEE 754 equality instance Eq BigFloat where BigFloat BF x == :: BigFloat -> BigFloat -> Bool == BigFloat BF y = IO Bool -> Bool forall a. IO a -> a unsafe (BF -> BF -> IO Bool cmpEq BF x BF y) -- | IEEE 754 comparisons instance Ord BigFloat where BigFloat BF x < :: BigFloat -> BigFloat -> Bool < BigFloat BF y = IO Bool -> Bool forall a. IO a -> a unsafe (BF -> BF -> IO Bool cmpLT BF x BF y) BigFloat BF x <= :: BigFloat -> BigFloat -> Bool <= BigFloat BF y = IO Bool -> Bool forall a. IO a -> a unsafe (BF -> BF -> IO Bool cmpLEQ BF x BF y) BigFloat BF x > :: BigFloat -> BigFloat -> Bool > BigFloat BF y = IO Bool -> Bool forall a. IO a -> a unsafe (BF -> BF -> IO Bool cmpLT BF y BF x) BigFloat BF x >= :: BigFloat -> BigFloat -> Bool >= BigFloat BF y = IO Bool -> Bool forall a. IO a -> a unsafe (BF -> BF -> IO Bool cmpLEQ BF y BF x) instance Hashable BigFloat where hashWithSalt :: Int -> BigFloat -> Int hashWithSalt Int s BigFloat x = Int -> BFRep -> Int forall a. Hashable a => Int -> a -> Int hashWithSalt Int s (BigFloat -> BFRep bfToRep BigFloat x) {-| Compare the two numbers. The special values are ordered like this: * -0 < 0 * NaN == NaN * NaN is larger than all other numbers Note that this differs from `(<=)` -} bfCompare :: BigFloat -> BigFloat -> Ordering bfCompare :: BigFloat -> BigFloat -> Ordering bfCompare (BigFloat BF x) (BigFloat BF y) = IO Ordering -> Ordering forall a. IO a -> a unsafe (BF -> BF -> IO Ordering cmp BF x BF y) -- | Is this a finite (i.e., non-infinite, non NaN) number. bfIsFinite :: BigFloat -> Bool bfIsFinite :: BigFloat -> Bool bfIsFinite (BigFloat BF x) = IO Bool -> Bool forall a. IO a -> a unsafe (BF -> IO Bool isFinite BF x) -- | Is this value NaN. bfIsNaN :: BigFloat -> Bool bfIsNaN :: BigFloat -> Bool bfIsNaN (BigFloat BF x) = IO Bool -> Bool forall a. IO a -> a unsafe (BF -> IO Bool M.isNaN BF x) -- | Is this value infinite bfIsInf :: BigFloat -> Bool bfIsInf :: BigFloat -> Bool bfIsInf (BigFloat BF x) = IO Bool -> Bool forall a. IO a -> a unsafe (BF -> IO Bool isInf BF x) -- | This is a "normal" number, which means it is not -- a NaN, not a zero, not infinite, and not subnormal. 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 -- | This number is "subnormal", which means it is among the smallest -- representable numbers for the given precision and exponent bits. -- These numbers differ from "normal" numbers in that they do not use -- an implicit leading 1 bit in the binary representation. bfIsSubnormal :: BFOpts -> BigFloat -> Bool bfIsSubnormal :: BFOpts -> BigFloat -> Bool bfIsSubnormal BFOpts opts BigFloat bf = BFOpts -> BFRep -> Bool repIsSubnormal BFOpts opts (BigFloat -> BFRep bfToRep BigFloat bf) -- | Get the sign of a number. Returns 'Nothing' if the number is `NaN`. bfSign :: BigFloat -> Maybe Sign bfSign :: BigFloat -> Maybe Sign bfSign (BigFloat BF x) = IO (Maybe Sign) -> Maybe Sign forall a. IO a -> a unsafe (BF -> IO (Maybe Sign) getSign BF x) -- | Compute the absolute value of a number. 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 -- | Is this value positive 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 -- | Is this value negative 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 -- | Get the exponent for the given number. -- Infinity, zero and NaN do not have an exponent. bfExponent :: BigFloat -> Maybe Int64 bfExponent :: BigFloat -> Maybe Int64 bfExponent (BigFloat BF x) = IO (Maybe Int64) -> Maybe Int64 forall a. IO a -> a unsafe (BF -> IO (Maybe Int64) getExp BF x) -- | Is this value a zero. bfIsZero :: BigFloat -> Bool bfIsZero :: BigFloat -> Bool bfIsZero (BigFloat BF x) = IO Bool -> Bool forall a. IO a -> a unsafe (BF -> IO Bool isZero BF x) -- | Negate a floating point number. bfNeg :: BigFloat -> BigFloat bfNeg :: BigFloat -> BigFloat bfNeg (BigFloat BF x) = (BF -> IO ()) -> BigFloat newBigFloat (\BF bf -> BF -> BF -> IO () setBF BF x BF bf IO () -> IO () -> IO () forall a b. IO a -> IO b -> IO b forall (m :: * -> *) a b. Monad m => m a -> m b -> m b >> BF -> IO () fneg BF bf) -- | Add two numbers useing the given options. bfAdd :: BFOpts -> BigFloat -> BigFloat -> (BigFloat,Status) bfAdd :: BFOpts -> BigFloat -> BigFloat -> (BigFloat, Status) bfAdd BFOpts opt (BigFloat BF x) (BigFloat BF y) = (BF -> IO Status) -> (BigFloat, Status) forall a. (BF -> IO a) -> (BigFloat, a) newBigFloat' (BFOpts -> BF -> BF -> BF -> IO Status fadd BFOpts opt BF x BF y) -- | Subtract two numbers useing the given options. bfSub :: BFOpts -> BigFloat -> BigFloat -> (BigFloat,Status) bfSub :: BFOpts -> BigFloat -> BigFloat -> (BigFloat, Status) bfSub BFOpts opt (BigFloat BF x) (BigFloat BF y) = (BF -> IO Status) -> (BigFloat, Status) forall a. (BF -> IO a) -> (BigFloat, a) newBigFloat' (BFOpts -> BF -> BF -> BF -> IO Status fsub BFOpts opt BF x BF y) -- | Multiply two numbers using the given options. bfMul :: BFOpts -> BigFloat -> BigFloat -> (BigFloat,Status) bfMul :: BFOpts -> BigFloat -> BigFloat -> (BigFloat, Status) bfMul BFOpts opt (BigFloat BF x) (BigFloat BF y) = (BF -> IO Status) -> (BigFloat, Status) forall a. (BF -> IO a) -> (BigFloat, a) newBigFloat' (BFOpts -> BF -> BF -> BF -> IO Status fmul BFOpts opt BF x BF y) -- | Multiply a number and a word, using the given options. bfMulWord :: BFOpts -> BigFloat -> Word64 -> (BigFloat,Status) bfMulWord :: BFOpts -> BigFloat -> Word64 -> (BigFloat, Status) bfMulWord BFOpts opt (BigFloat BF x) Word64 y = (BF -> IO Status) -> (BigFloat, Status) forall a. (BF -> IO a) -> (BigFloat, a) newBigFloat' (BFOpts -> BF -> Word64 -> BF -> IO Status fmulWord BFOpts opt BF x Word64 y) -- | Multiply a number and an int, using the given options. bfMulInt :: BFOpts -> BigFloat -> Int64 -> (BigFloat,Status) bfMulInt :: BFOpts -> BigFloat -> Int64 -> (BigFloat, Status) bfMulInt BFOpts opt (BigFloat BF x) Int64 y = (BF -> IO Status) -> (BigFloat, Status) forall a. (BF -> IO a) -> (BigFloat, a) newBigFloat' (BFOpts -> BF -> Int64 -> BF -> IO Status fmulInt BFOpts opt BF x Int64 y) -- | Multiply a number by @2^e@. bfMul2Exp :: BFOpts -> BigFloat -> Int -> (BigFloat,Status) bfMul2Exp :: BFOpts -> BigFloat -> Int -> (BigFloat, Status) bfMul2Exp BFOpts opt (BigFloat BF x) Int e = (BF -> IO Status) -> (BigFloat, Status) 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) -- | Divide two numbers useing the given options. bfDiv :: BFOpts -> BigFloat -> BigFloat -> (BigFloat,Status) bfDiv :: BFOpts -> BigFloat -> BigFloat -> (BigFloat, Status) bfDiv BFOpts opt (BigFloat BF x) (BigFloat BF y) = (BF -> IO Status) -> (BigFloat, Status) forall a. (BF -> IO a) -> (BigFloat, a) newBigFloat' (BFOpts -> BF -> BF -> BF -> IO Status fdiv BFOpts opt BF x BF y) -- | Compute the remainder @x - y * n@ where @n@ is the integer -- nearest to @x/y@ (with ties broken to even values of @n@). bfRem :: BFOpts -> BigFloat -> BigFloat -> (BigFloat, Status) bfRem :: BFOpts -> BigFloat -> BigFloat -> (BigFloat, Status) bfRem BFOpts opt (BigFloat BF x) (BigFloat BF y) = (BF -> IO Status) -> (BigFloat, Status) forall a. (BF -> IO a) -> (BigFloat, a) newBigFloat' (BFOpts -> BF -> BF -> BF -> IO Status frem BFOpts opt BF x BF y) -- | Compute the fused-multiply-add @(x*y)+z@ 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) = (BF -> IO Status) -> (BigFloat, Status) forall a. (BF -> IO a) -> (BigFloat, a) newBigFloat' (BFOpts -> BF -> BF -> BF -> BF -> IO Status ffma BFOpts opt BF x BF y BF z) -- | Square root of two numbers useing the given options. bfSqrt :: BFOpts -> BigFloat -> (BigFloat,Status) bfSqrt :: BFOpts -> BigFloat -> (BigFloat, Status) bfSqrt BFOpts opt (BigFloat BF x) = (BF -> IO Status) -> (BigFloat, Status) forall a. (BF -> IO a) -> (BigFloat, a) newBigFloat' (BFOpts -> BF -> BF -> IO Status fsqrt BFOpts opt BF x) -- | Round to a float matching the input parameters. bfRoundFloat :: BFOpts -> BigFloat -> (BigFloat,Status) bfRoundFloat :: BFOpts -> BigFloat -> (BigFloat, Status) bfRoundFloat BFOpts opt (BigFloat BF x) = (BF -> IO Status) -> (BigFloat, Status) 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 ) -- | Round to an integer using the given rounding mode. bfRoundInt :: RoundMode -> BigFloat -> (BigFloat,Status) bfRoundInt :: RoundMode -> BigFloat -> (BigFloat, Status) bfRoundInt RoundMode r (BigFloat BF x) = (BF -> IO Status) -> (BigFloat, Status) 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 ) -- | Exponentiate a word to a positive integer power. bfPow :: BFOpts -> BigFloat -> BigFloat -> (BigFloat, Status) bfPow :: BFOpts -> BigFloat -> BigFloat -> (BigFloat, Status) bfPow BFOpts opts (BigFloat BF x) (BigFloat BF y) = (BF -> IO Status) -> (BigFloat, Status) forall a. (BF -> IO a) -> (BigFloat, a) newBigFloat' (BFOpts -> BF -> BF -> BF -> IO Status fpow BFOpts opts BF x BF y) -- | Constant to a 'Double' bfToDouble :: RoundMode -> BigFloat -> (Double, Status) bfToDouble :: RoundMode -> BigFloat -> (Double, Status) bfToDouble RoundMode r (BigFloat BF x) = IO (Double, Status) -> (Double, Status) forall a. IO a -> a unsafe (RoundMode -> BF -> IO (Double, Status) toDouble RoundMode r BF x) -- | Render as a 'String', using the given settings. bfToString :: Int {- ^ Base -} -> ShowFmt -> BigFloat -> String bfToString :: Int -> ShowFmt -> BigFloat -> [Char] bfToString Int radix ShowFmt opts (BigFloat BF x) = IO [Char] -> [Char] forall a. IO a -> a unsafe (Int -> ShowFmt -> BF -> IO [Char] toString Int radix ShowFmt opts BF x) -- | Parse a number from the given string. -- Returns @NaN` if the string does not correspond to a number we recognize. bfFromString :: Int {- ^ Base -} -> BFOpts -> String -> (BigFloat,Status) bfFromString :: Int -> BFOpts -> [Char] -> (BigFloat, Status) bfFromString Int radix BFOpts opts [Char] str = (BF -> IO Status) -> (BigFloat, Status) forall a. (BF -> IO a) -> (BigFloat, a) newBigFloat' \BF bf -> do (Status status,Int _,Bool usedAll) <- Int -> BFOpts -> [Char] -> BF -> IO (Status, Int, Bool) setString Int radix BFOpts opts [Char] str BF bf if Bool usedAll then Status -> IO Status forall a. a -> IO a forall (f :: * -> *) a. Applicative f => a -> f a pure Status status else do BF -> IO () setNaN BF bf Status -> IO Status forall a. a -> IO a forall (f :: * -> *) a. Applicative f => a -> f a pure Status Ok -- | The float as an exponentiated 'Integer'. bfToRep :: BigFloat -> BFRep bfToRep :: BigFloat -> BFRep bfToRep (BigFloat BF x) = IO BFRep -> BFRep forall a. IO a -> a unsafe (BF -> IO BFRep toRep BF x) -- | Make a number mutable. -- WARNING: This does not copy the number, -- so it could break referential transperancy. bfUnsafeThaw :: BigFloat -> BF bfUnsafeThaw :: BigFloat -> BF bfUnsafeThaw (BigFloat BF x) = BF x -- | Make a number immutable. -- WARNING: This does not copy the number, -- so it could break referential transperancy. bfUnsafeFreeze :: BF -> BigFloat bfUnsafeFreeze :: BF -> BigFloat bfUnsafeFreeze = BF -> BigFloat BigFloat -------------------------------------------------------------------------------- -- | Make a float using "raw" bits representing the bitvector -- representation of a floating-point value with the -- exponent and precision bits given by the options. bfFromBits :: BFOpts -> Integer {- ^ Raw bits -} -> BigFloat bfFromBits :: BFOpts -> Integer -> BigFloat bfFromBits BFOpts opts Integer bits | Int expoBiased Int -> Int -> Bool forall a. Eq a => a -> a -> Bool == Int 0 Bool -> Bool -> Bool && Integer mant Integer -> Integer -> Bool forall a. Eq a => a -> a -> Bool == Integer 0 = -- zero if Bool isNeg then BigFloat bfNegZero else BigFloat bfPosZero | Int expoBiased Int -> Int -> Bool forall a. Eq a => a -> a -> Bool == Int eMask Bool -> Bool -> Bool && Integer mant Integer -> Integer -> Bool forall a. Eq a => a -> a -> Bool == Integer 0 = -- infinity if Bool isNeg then BigFloat bfNegInf else BigFloat bfPosInf | Int expoBiased Int -> Int -> Bool forall a. Eq a => a -> a -> Bool == Int eMask = BigFloat bfNaN -- NaN | Int expoBiased Int -> Int -> Bool forall a. Eq a => a -> a -> Bool == Int 0 = -- Subnormal case BFOpts -> BigFloat -> Int -> (BigFloat, Status) bfMul2Exp BFOpts opts' (Integer -> BigFloat bfFromInteger Integer mant) (Int expoVal Int -> Int -> Int 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) -> [Char] -> BigFloat forall a. HasCallStack => [Char] -> a error ([Char] -> BigFloat) -> [Char] -> BigFloat forall a b. (a -> b) -> a -> b $ [[Char]] -> [Char] unwords [[Char] "bfFromBits", [Char] "subnormal case", [Char] "Unexpected status:", Status -> [Char] forall a. Show a => a -> [Char] show Status s, Integer -> [Char] forall a. Show a => a -> [Char] show Integer bits, Integer -> [Char] forall a. Show a => a -> [Char] show Integer mant, Int -> [Char] forall a. Show a => a -> [Char] show Int expoVal, Int -> [Char] forall a. Show a => a -> [Char] show Int e, Word -> [Char] forall a. Show a => a -> [Char] show Word p ] | Bool otherwise = -- Normal 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) -> [Char] -> BigFloat forall a. HasCallStack => [Char] -> a error ([Char] -> BigFloat) -> [Char] -> BigFloat forall a b. (a -> b) -> a -> b $ [[Char]] -> [Char] unwords [[Char] "bfFromBits", [Char] "normal case", [Char] "Unexpected status:", Status -> [Char] forall a. Show a => a -> [Char] show Status s, Integer -> [Char] forall a. Show a => a -> [Char] show Integer bits, Integer -> [Char] forall a. Show a => a -> [Char] show Integer mantVal, Int -> [Char] forall a. Show a => a -> [Char] show Int expoVal, Int -> [Char] forall a. Show a => a -> [Char] show Int e, Word -> [Char] forall a. Show a => a -> [Char] 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 BFOpts -> BFOpts -> BFOpts forall a. Semigroup a => a -> a -> a <> BFOpts allowSubnormal p' :: Int p' = Word -> Int forall a b. (Integral a, Num b) => a -> b fromIntegral Word p Int -> Int -> Int forall a. Num a => a -> a -> a - Int 1 :: Int eMask :: Int eMask = (Int 1 Int -> Int -> Int forall a. Bits a => a -> Int -> a `shiftL` Int e) Int -> Int -> Int forall a. Num a => a -> a -> a - Int 1 :: Int pMask :: Integer pMask = (Integer 1 Integer -> Int -> Integer forall a. Bits a => a -> Int -> a `shiftL` Int p') Integer -> Integer -> Integer forall a. Num a => a -> a -> a - Integer 1 :: Integer isNeg :: Bool isNeg = Integer -> Int -> Bool forall a. Bits a => a -> Int -> Bool testBit Integer bits (Int e Int -> Int -> Int forall a. Num a => a -> a -> a + Int p') mant :: Integer mant = Integer pMask Integer -> Integer -> Integer forall a. Bits a => a -> a -> a .&. Integer bits :: Integer mantVal :: Integer mantVal = Integer mant Integer -> Int -> Integer forall a. Bits a => a -> Int -> a `setBit` Int p' :: Integer -- accounts for the implicit 1 bit expoBiased :: Int expoBiased = Int eMask Int -> Int -> Int forall a. Bits a => a -> a -> a .&. Integer -> Int forall a. Num a => Integer -> a fromInteger (Integer bits Integer -> Int -> Integer forall a. Bits a => a -> Int -> a `shiftR` Int p') :: Int bias :: Int bias = Int eMask Int -> Int -> Int forall a. Bits a => a -> Int -> a `shiftR` Int 1 :: Int expoVal :: Int expoVal = Int expoBiased Int -> Int -> Int forall a. Num a => a -> a -> a - Int bias Int -> Int -> Int forall a. Num a => a -> a -> a - Int -> Int forall a b. (Integral a, Num b) => a -> b fromIntegral Int p' :: Int -- | Turn a float into raw bits. -- @NaN@ is represented as a positive "quiet" @NaN@ -- (most significant bit in the significand is set, the rest of it is 0). bfToBits :: BFOpts -> BigFloat -> Integer bfToBits :: BFOpts -> BigFloat -> Integer bfToBits BFOpts opts BigFloat bf = Integer res where res :: Integer res = (Integer isNeg Integer -> Int -> Integer forall a. Bits a => a -> Int -> a `shiftL` (Int eInt -> Int -> Int forall a. Num a => a -> a -> a +Int p')) Integer -> Integer -> Integer forall a. Bits a => a -> a -> a .|. (Integer expBiased Integer -> Int -> Integer forall a. Bits a => a -> Int -> a `shiftL` Int p') Integer -> Integer -> Integer forall a. Bits a => a -> a -> a .|. (Integer mant Integer -> Int -> Integer 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' = Word -> Int forall a b. (Integral a, Num b) => a -> b fromIntegral Word p Int -> Int -> Int forall a. Num a => a -> a -> a - Int 1 :: Int eMask :: Integer eMask = (Integer 1 Integer -> Int -> Integer forall a. Bits a => a -> Int -> a `shiftL` Int e) Integer -> Integer -> Integer forall a. Num a => a -> a -> a - Integer 1 :: Integer pMask :: Integer pMask = (Integer 1 Integer -> Int -> Integer forall a. Bits a => a -> Int -> a `shiftL` Int p') Integer -> Integer -> Integer 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 Integer -> Int -> Integer forall a. Bits a => a -> Int -> a `shiftL` (Int p' Int -> Int -> Int 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 Integer -> Integer -> Bool forall a. Ord a => a -> a -> Bool <= Integer 0 -> (Integer 0, Integer i Integer -> Int -> Integer forall a. Bits a => a -> Int -> a `shiftL` (Int p'Int -> Int -> Int forall a. Num a => a -> a -> a -Int mInt -> Int -> Int forall a. Num a => a -> a -> a -Int 1Int -> Int -> Int forall a. Num a => a -> a -> a +Integer -> Int forall a. Num a => Integer -> a fromInteger Integer ex)) -- subnormal case | Bool otherwise -> (Integer ex, (Integer i Integer -> Int -> Integer forall a. Bits a => a -> Int -> a `shiftL` (Int p' Int -> Int -> Int forall a. Num a => a -> a -> a - Int m)) Integer -> Integer -> Integer forall a. Bits a => a -> a -> a .&. Integer pMask) -- normal case where m :: Int m = Int -> Integer -> Int forall {t} {t}. (Num t, Num t, Bits t) => t -> t -> t msb Int 0 Integer i Int -> Int -> Int forall a. Num a => a -> a -> a - Int 1 bias :: Integer bias = Integer eMask Integer -> Int -> Integer forall a. Bits a => a -> Int -> a `shiftR` Int 1 ex :: Integer ex = Int64 -> Integer forall a. Integral a => a -> Integer toInteger Int64 ev Integer -> Integer -> Integer forall a. Num a => a -> a -> a + Integer bias Integer -> Integer -> Integer forall a. Num a => a -> a -> a + Int -> Integer 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 t -> t -> Bool forall a. Eq a => a -> a -> Bool == t 0 then t n else t -> t -> t msb (t nt -> t -> t forall a. Num a => a -> a -> a +t 1) (t j t -> Int -> t forall a. Bits a => a -> Int -> a `shiftR` Int 1) -- | test if a given big float representation is subnormal repIsSubnormal :: BFOpts -> BFRep -> Bool repIsSubnormal :: BFOpts -> BFRep -> Bool repIsSubnormal BFOpts opts (BFRep Sign _s (Num Integer i Int64 ev)) = Integer ex Integer -> Integer -> Bool forall a. Ord a => a -> a -> Bool <= Integer 0 where e :: Int e = BFOpts -> Int getExpBits BFOpts opts eMask :: Integer eMask = (Integer 1 Integer -> Int -> Integer forall a. Bits a => a -> Int -> a `shiftL` Int e) Integer -> Integer -> Integer forall a. Num a => a -> a -> a - Integer 1 :: Integer bias :: Integer bias = Integer eMask Integer -> Int -> Integer forall a. Bits a => a -> Int -> a `shiftR` Int 1 m :: Int m = Int -> Integer -> Int forall {t} {t}. (Num t, Num t, Bits t) => t -> t -> t msb (Int 0 :: Int) Integer i Int -> Int -> Int forall a. Num a => a -> a -> a - Int 1 ex :: Integer ex = Int64 -> Integer forall a. Integral a => a -> Integer toInteger Int64 ev Integer -> Integer -> Integer forall a. Num a => a -> a -> a + Integer bias Integer -> Integer -> Integer forall a. Num a => a -> a -> a + Int -> Integer forall a. Integral a => a -> Integer toInteger Int m msb :: t -> t -> t msb !t n t j = if t j t -> t -> Bool forall a. Eq a => a -> a -> Bool == t 0 then t n else t -> t -> t msb (t nt -> t -> t forall a. Num a => a -> a -> a +t 1) (t j t -> Int -> t forall a. Bits a => a -> Int -> a `shiftR` Int 1) repIsSubnormal BFOpts _opts BFRep _rep = Bool False
Fetched URL: http://hackage.haskell.org/package/libBF-0.6.8/docs/src/LibBF.html#bfFromInteger
Alternative Proxies: