    ---------------------------------------------------------------------------
    -- |
    -- 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)
                 }