---------------------------------------------------------------------------
-- |
-- Module      :  Data.Numbers.CrackNum.Data
-- Copyright   :  (c) Levent Erkok
-- License     :  BSD3
-- Maintainer  :  erkokl@gmail.com
-- Stability   :  experimental
--
-- Internal representation of FP values
-----------------------------------------------------------------------------

module Data.Numbers.CrackNum.Data where

-- | Floating point precision
data Precision = HP    -- ^ Half   precision; 16 bits = 1 sign +  5 exponent + 10 mantissa
               | SP    -- ^ Single precision; 32 bits = 1 sign +  8 exponent + 23 mantissa
               | DP    -- ^ Double precision; 64 bits = 1 sign + 11 exponent + 52 mantissa
               deriving (Precision -> Precision -> Bool
(Precision -> Precision -> Bool)
-> (Precision -> Precision -> Bool) -> Eq Precision
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Precision -> Precision -> Bool
$c/= :: Precision -> Precision -> Bool
== :: Precision -> Precision -> Bool
$c== :: Precision -> Precision -> Bool
Eq, Int -> Precision -> ShowS
[Precision] -> ShowS
Precision -> String
(Int -> Precision -> ShowS)
-> (Precision -> String)
-> ([Precision] -> ShowS)
-> Show Precision
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Precision] -> ShowS
$cshowList :: [Precision] -> ShowS
show :: Precision -> String
$cshow :: Precision -> String
showsPrec :: Int -> Precision -> ShowS
$cshowsPrec :: Int -> Precision -> ShowS
Show)

-- | Integer/Word precision
data IPrecision = W8   -- ^  8-bit unsigned (byte)
                | I8   -- ^  8-bit signed
                | W16  -- ^ 16-bit unsigned (word)
                | I16  -- ^ 16-bit signed
                | W32  -- ^ 32-bit unsigned (double-word)
                | I32  -- ^ 32-bit signed
                | W64  -- ^ 64-bit unsigned (quad-word)
                | I64  -- ^ 64-bit signed
                deriving IPrecision -> IPrecision -> Bool
(IPrecision -> IPrecision -> Bool)
-> (IPrecision -> IPrecision -> Bool) -> Eq IPrecision
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: IPrecision -> IPrecision -> Bool
$c/= :: IPrecision -> IPrecision -> Bool
== :: IPrecision -> IPrecision -> Bool
$c== :: IPrecision -> IPrecision -> Bool
Eq

-- | Kinds of floating point values
data Kind = Zero    Bool   -- ^ Zero: 0. If Bool is true, then this is -0; otherwise +0.
          | Infty   Bool   -- ^ Infinity: oo. If Bool is true, then this is -oo, otherwie +oo.
          | SNaN           -- ^ The signaling-NaN.
          | QNaN           -- ^ The quiet-NaN.
          | Denormal       -- ^ Denormalized number, i.e., leading bit is not 1
          | Normal         -- ^ Normal value.

-- | Determine if we have a NaN value
isNaNKind :: Kind -> Bool
isNaNKind :: Kind -> Bool
isNaNKind SNaN = Bool
True
isNaNKind QNaN = Bool
True
isNaNKind _    = Bool
False

-- | Show instance for integer-precisions
instance Show IPrecision where
  show :: IPrecision -> String
show W8  = "Unsigned Byte"
  show I8  = "Signed Byte"
  show W16 = "Unsigned Word"
  show I16 = "Signed Word"
  show W32 = "Unsigned Double"
  show I32 = "Signed Double"
  show W64 = "Unsigned Quad"
  show I64 = "Signed Quad"

-- | Complete internal representation for a floating-point number
data FP = FP { FP -> Integer
intVal    :: Integer      -- ^ The value as represented as a full Integer. Storage purposes only.
             , FP -> Precision
prec      :: Precision    -- ^ FP precision.
             , FP -> Bool
sign      :: Bool         -- ^ Sign. If True then negative, otherwise positive.
             , FP -> Int
stExpt    :: Int          -- ^ The exponent as it is stored.
             , FP -> Int
bias      :: Int          -- ^ The implicit bias of the exponent.
             , FP -> Int
expt      :: Int          -- ^ The actual exponent.
             , FP -> [Bool]
fracBits  :: [Bool]       -- ^ Bits in the fractional part
             , FP -> String
bitLayOut :: String       -- ^ Layout representation
             , FP -> Kind
kind      :: Kind         -- ^ Floating-point kind (i.e., value)
             }