    {-# LANGUAGE CPP #-}

    -- |
    -- Module      : Data.ByteString.Builder.RealFloat.F2S
    -- Copyright   : (c) Lawrence Wu 2021
    -- License     : BSD-style
    -- Maintainer  : lawrencejwu@gmail.com
    --
    -- Implementation of float-to-string conversion

    module Data.ByteString.Builder.RealFloat.F2S
        ( FloatingDecimal(..)
        , f2s
        , f2Intermediate
        ) where

    import Control.Arrow (first)
    import Data.Bits ((.|.), (.&.), unsafeShiftL, unsafeShiftR)
    import Data.ByteString.Builder.Internal (Builder)
    import Data.ByteString.Builder.Prim (primBounded)
    import Data.ByteString.Builder.RealFloat.Internal
    import GHC.Int (Int32(..))
    import GHC.Word (Word32(..), Word64(..))

    #if !PURE_HASKELL
    import GHC.Ptr (Ptr(..))
    #endif

    -- See Data.ByteString.Builder.RealFloat.TableGenerator for a high-level
    -- explanation of the ryu algorithm

    #if !PURE_HASKELL
    -- | Table of 2^k / 5^q + 1
    --
    -- > fmap (finv float_pow5_inv_bitcount) [0..float_max_inv_split]
    foreign import ccall "&hs_bytestring_float_pow5_inv_split"
      float_pow5_inv_split :: Ptr Word64

    -- | Table of 5^(-e2-q) / 2^k + 1
    --
    -- > fmap (fnorm float_pow5_bitcount) [0..float_max_split]
    foreign import ccall "&hs_bytestring_float_pow5_split"
      float_pow5_split :: Ptr Word64
    #endif

    -- | Number of mantissa bits of a 32-bit float. The number of significant bits
    -- (floatDigits (undefined :: Float)) is 24 since we have a leading 1 for
    -- normal floats and 0 for subnormal floats
    float_mantissa_bits :: Int
    float_mantissa_bits :: Int
    float_mantissa_bits = Int
    23

    -- | Number of exponent bits of a 32-bit float
    float_exponent_bits :: Int
    float_exponent_bits :: Int
    float_exponent_bits = Int
    8

    -- | Bias in encoded 32-bit float representation (2^7 - 1)
    float_bias :: Int
    float_bias :: Int
    float_bias = Int
    127

    data FloatingDecimal = FloatingDecimal
      { FloatingDecimal -> Word32
    fmantissa :: !Word32
      , FloatingDecimal -> Int32
    fexponent :: !Int32
      } deriving (Int -> FloatingDecimal -> ShowS
    [FloatingDecimal] -> ShowS
    FloatingDecimal -> String
    (Int -> FloatingDecimal -> ShowS)
    -> (FloatingDecimal -> String)
    -> ([FloatingDecimal] -> ShowS)
    -> Show FloatingDecimal
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> FloatingDecimal -> ShowS
    showsPrec :: Int -> FloatingDecimal -> ShowS
    $cshow :: FloatingDecimal -> String
    show :: FloatingDecimal -> String
    $cshowList :: [FloatingDecimal] -> ShowS
    showList :: [FloatingDecimal] -> ShowS
    Show, FloatingDecimal -> FloatingDecimal -> Bool
    (FloatingDecimal -> FloatingDecimal -> Bool)
    -> (FloatingDecimal -> FloatingDecimal -> Bool)
    -> Eq FloatingDecimal
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: FloatingDecimal -> FloatingDecimal -> Bool
    == :: FloatingDecimal -> FloatingDecimal -> Bool
    $c/= :: FloatingDecimal -> FloatingDecimal -> Bool
    /= :: FloatingDecimal -> FloatingDecimal -> Bool
    Eq)

    -- | Multiply a 32-bit number with a 64-bit number while keeping the upper 64
    -- bits. Then shift by specified amount minus 32
    mulShift32 :: Word32 -> Word64 -> Int -> Word32
    mulShift32 :: Word32 -> Word64 -> Int -> Word32
    mulShift32 Word32
    m Word64
    factor Int
    shift =
      let factorLo :: Word64
    factorLo = Word64
    factor Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .&. Int -> Word64
    forall a. (Bits a, Integral a) => Int -> a
    mask Int
    32
          factorHi :: Word64
    factorHi = Word64
    factor Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    `unsafeShiftR` Int
    32
          bits0 :: Word64
    bits0 = Word32 -> Word64
    word32ToWord64 Word32
    m Word64 -> Word64 -> Word64
    forall a. Num a => a -> a -> a
    * Word64
    factorLo
          bits1 :: Word64
    bits1 = Word32 -> Word64
    word32ToWord64 Word32
    m Word64 -> Word64 -> Word64
    forall a. Num a => a -> a -> a
    * Word64
    factorHi
          total :: Word64
    total  = (Word64
    bits0 Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    `unsafeShiftR` Int
    32) Word64 -> Word64 -> Word64
    forall a. Num a => a -> a -> a
    + Word64
    bits1
       in Word64 -> Word32
    word64ToWord32 (Word64 -> Word32) -> Word64 -> Word32
    forall a b. (a -> b) -> a -> b
    $ Word64
    total Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    `unsafeShiftR` (Int
    shift Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    32)

    -- | Index into the 64-bit word lookup table float_pow5_inv_split
    get_float_pow5_inv_split :: Int -> Word64
    #if !PURE_HASKELL
    get_float_pow5_inv_split :: Int -> Word64
    get_float_pow5_inv_split = Ptr Word64 -> Int -> Word64
    getWord64At Ptr Word64
    float_pow5_inv_split
    #else
    -- > putStr $ case64 (finv float_pow5_inv_bitcount) [0..float_max_inv_split]
    get_float_pow5_inv_split i = case i of
      0  -> 0x800000000000001
      1  -> 0x666666666666667
      2  -> 0x51eb851eb851eb9
      3  -> 0x4189374bc6a7efa
      4  -> 0x68db8bac710cb2a
      5  -> 0x53e2d6238da3c22
      6  -> 0x431bde82d7b634e
      7  -> 0x6b5fca6af2bd216
      8  -> 0x55e63b88c230e78
      9  -> 0x44b82fa09b5a52d
      10 -> 0x6df37f675ef6eae
      11 -> 0x57f5ff85e592558
      12 -> 0x465e6604b7a8447
      13 -> 0x709709a125da071
      14 -> 0x5a126e1a84ae6c1
      15 -> 0x480ebe7b9d58567
      16 -> 0x734aca5f6226f0b
      17 -> 0x5c3bd5191b525a3
      18 -> 0x49c97747490eae9
      19 -> 0x760f253edb4ab0e
      20 -> 0x5e72843249088d8
      21 -> 0x4b8ed0283a6d3e0
      22 -> 0x78e480405d7b966
      23 -> 0x60b6cd004ac9452
      24 -> 0x4d5f0a66a23a9db
      25 -> 0x7bcb43d769f762b
      26 -> 0x63090312bb2c4ef
      27 -> 0x4f3a68dbc8f03f3
      28 -> 0x7ec3daf94180651
      29 -> 0x65697bfa9acd1da
      _  -> 0x51212ffbaf0a7e2
    #endif

    -- | Index into the 64-bit word lookup table float_pow5_split
    get_float_pow5_split :: Int -> Word64
    #if !PURE_HASKELL
    get_float_pow5_split :: Int -> Word64
    get_float_pow5_split = Ptr Word64 -> Int -> Word64
    getWord64At Ptr Word64
    float_pow5_split
    #else
    -- > putStr $ case64 (fnorm float_pow5_bitcount) [0..float_max_split]
    get_float_pow5_split i = case i of
      0  -> 0x1000000000000000
      1  -> 0x1400000000000000
      2  -> 0x1900000000000000
      3  -> 0x1f40000000000000
      4  -> 0x1388000000000000
      5  -> 0x186a000000000000
      6  -> 0x1e84800000000000
      7  -> 0x1312d00000000000
      8  -> 0x17d7840000000000
      9  -> 0x1dcd650000000000
      10 -> 0x12a05f2000000000
      11 -> 0x174876e800000000
      12 -> 0x1d1a94a200000000
      13 -> 0x12309ce540000000
      14 -> 0x16bcc41e90000000
      15 -> 0x1c6bf52634000000
      16 -> 0x11c37937e0800000
      17 -> 0x16345785d8a00000
      18 -> 0x1bc16d674ec80000
      19 -> 0x1158e460913d0000
      20 -> 0x15af1d78b58c4000
      21 -> 0x1b1ae4d6e2ef5000
      22 -> 0x10f0cf064dd59200
      23 -> 0x152d02c7e14af680
      24 -> 0x1a784379d99db420
      25 -> 0x108b2a2c28029094
      26 -> 0x14adf4b7320334b9
      27 -> 0x19d971e4fe8401e7
      28 -> 0x1027e72f1f128130
      29 -> 0x1431e0fae6d7217c
      30 -> 0x193e5939a08ce9db
      31 -> 0x1f8def8808b02452
      32 -> 0x13b8b5b5056e16b3
      33 -> 0x18a6e32246c99c60
      34 -> 0x1ed09bead87c0378
      35 -> 0x13426172c74d822b
      36 -> 0x1812f9cf7920e2b6
      37 -> 0x1e17b84357691b64
      38 -> 0x12ced32a16a1b11e
      39 -> 0x178287f49c4a1d66
      40 -> 0x1d6329f1c35ca4bf
      41 -> 0x125dfa371a19e6f7
      42 -> 0x16f578c4e0a060b5
      43 -> 0x1cb2d6f618c878e3
      44 -> 0x11efc659cf7d4b8d
      45 -> 0x166bb7f0435c9e71
      _  -> 0x1c06a5ec5433c60d
    #endif

    -- | Take the high bits of m * 2^k / 5^q / 2^-e2+q+k
    mulPow5InvDivPow2 :: Word32 -> Int -> Int -> Word32
    mulPow5InvDivPow2 :: Word32 -> Int -> Int -> Word32
    mulPow5InvDivPow2 Word32
    m Int
    q Int
    j = Word32 -> Word64 -> Int -> Word32
    mulShift32 Word32
    m (Int -> Word64
    get_float_pow5_inv_split Int
    q) Int
    j

    -- | Take the high bits of m * 5^-e2-q / 2^k / 2^q-k
    mulPow5DivPow2 :: Word32 -> Int -> Int -> Word32
    mulPow5DivPow2 :: Word32 -> Int -> Int -> Word32
    mulPow5DivPow2 Word32
    m Int
    i Int
    j = Word32 -> Word64 -> Int -> Word32
    mulShift32 Word32
    m (Int -> Word64
    get_float_pow5_split Int
    i) Int
    j

    -- | Handle case e2 >= 0
    f2dGT :: Int32 -> Word32 -> Word32 -> Word32 -> (BoundsState Word32, Int32)
    f2dGT :: Int32 -> Word32 -> Word32 -> Word32 -> (BoundsState Word32, Int32)
    f2dGT Int32
    e2' Word32
    u Word32
    v Word32
    w =
      let e2 :: Int
    e2 = Int32 -> Int
    int32ToInt Int32
    e2'
          -- q = e10 = log_10(2^e2)
          q :: Int
    q = Int -> Int
    log10pow2 Int
    e2
          -- k = B0 + log_2(5^q)
          k :: Int
    k = Int
    float_pow5_inv_bitcount Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int -> Int
    pow5bits Int
    q Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    1
          i :: Int
    i = -Int
    e2 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    q Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    k
          -- (u, v, w) * 2^k / 5^q / 2^-e2+q+k
          u' :: Word32
    u' = Word32 -> Int -> Int -> Word32
    mulPow5InvDivPow2 Word32
    u Int
    q Int
    i
          v' :: Word32
    v' = Word32 -> Int -> Int -> Word32
    mulPow5InvDivPow2 Word32
    v Int
    q Int
    i
          w' :: Word32
    w' = Word32 -> Int -> Int -> Word32
    mulPow5InvDivPow2 Word32
    w Int
    q Int
    i
          !lastRemoved :: Word32
    lastRemoved =
            if Int
    q Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Int
    0 Bool -> Bool -> Bool
    && Word32 -> Word32
    fquot10 (Word32
    w' Word32 -> Word32 -> Word32
    forall a. Num a => a -> a -> a
    - Word32
    1) Word32 -> Word32 -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Word32 -> Word32
    fquot10 Word32
    u'
              -- We need to know one removed digit even if we are not going to loop
              -- below. We could use q = X - 1 above, except that would require 33
              -- bits for the result, and we've found that 32-bit arithmetic is
              -- faster even on 64-bit machines.
              then let l :: Int
    l = Int
    float_pow5_inv_bitcount Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int -> Int
    pow5bits (Int
    q Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    1) Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    1
                    in Word32 -> Word32
    frem10 (Word32 -> Int -> Int -> Word32
    mulPow5InvDivPow2 Word32
    v (Int
    q Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    1) (-Int
    e2 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    q Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    1 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    l))
              else Word32
    0
          !(Bool
    vvTrailing, Bool
    vuTrailing, Word32
    vw') =
            case () of
              ()
    _ | Int
    q Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    9 Bool -> Bool -> Bool
    && Word32 -> Word32
    frem5 Word32
    v Word32 -> Word32 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word32
    0
                    -> (Word32 -> Int -> Bool
    forall a. Mantissa a => a -> Int -> Bool
    multipleOfPowerOf5 Word32
    v Int
    q, Bool
    False, Word32
    w')
                | Int
    q Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    9 Bool -> Bool -> Bool
    && Word32 -> Bool
    forall a. Mantissa a => a -> Bool
    acceptBounds Word32
    v
                    -> (Bool
    False, Word32 -> Int -> Bool
    forall a. Mantissa a => a -> Int -> Bool
    multipleOfPowerOf5 Word32
    u Int
    q, Word32
    w')
                | Int
    q Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    9
                    -> (Bool
    False, Bool
    False, Word32
    w' Word32 -> Word32 -> Word32
    forall a. Num a => a -> a -> a
    - Bool -> Word32
    boolToWord32 (Word32 -> Int -> Bool
    forall a. Mantissa a => a -> Int -> Bool
    multipleOfPowerOf5 Word32
    w Int
    q))
                | Bool
    otherwise
                    -> (Bool
    False, Bool
    False, Word32
    w')
       in (Word32
    -> Word32 -> Word32 -> Word32 -> Bool -> Bool -> BoundsState Word32
    forall a. a -> a -> a -> a -> Bool -> Bool -> BoundsState a
    BoundsState Word32
    u' Word32
    v' Word32
    vw' Word32
    lastRemoved Bool
    vuTrailing Bool
    vvTrailing, Int -> Int32
    intToInt32 Int
    q)

    -- | Handle case e2 < 0
    f2dLT :: Int32 -> Word32 -> Word32 -> Word32 -> (BoundsState Word32, Int32)
    f2dLT :: Int32 -> Word32 -> Word32 -> Word32 -> (BoundsState Word32, Int32)
    f2dLT Int32
    e2' Word32
    u Word32
    v Word32
    w =
      let e2 :: Int
    e2 = Int32 -> Int
    int32ToInt Int32
    e2'
          q :: Int
    q = Int -> Int
    log10pow5 (-Int
    e2)
          e10 :: Int
    e10 = Int
    q Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    e2
          i :: Int
    i = (-Int
    e2) Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    q
          -- k = log_2(5^-e2-q) - B1
          k :: Int
    k = Int -> Int
    pow5bits Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    float_pow5_bitcount
          j :: Int
    j = Int
    q Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    k
          -- (u, v, w) * 5^-e2-q / 2^k / 2^q-k
          u' :: Word32
    u' = Word32 -> Int -> Int -> Word32
    mulPow5DivPow2 Word32
    u Int
    i Int
    j
          v' :: Word32
    v' = Word32 -> Int -> Int -> Word32
    mulPow5DivPow2 Word32
    v Int
    i Int
    j
          w' :: Word32
    w' = Word32 -> Int -> Int -> Word32
    mulPow5DivPow2 Word32
    w Int
    i Int
    j
          !lastRemoved :: Word32
    lastRemoved =
            if Int
    q Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Int
    0 Bool -> Bool -> Bool
    && Word32 -> Word32
    fquot10 (Word32
    w' Word32 -> Word32 -> Word32
    forall a. Num a => a -> a -> a
    - Word32
    1) Word32 -> Word32 -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Word32 -> Word32
    fquot10 Word32
    u'
              then let j' :: Int
    j' = Int
    q Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    1 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - (Int -> Int
    pow5bits (Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1) Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    float_pow5_bitcount)
                    in Word32 -> Word32
    frem10 (Word32 -> Int -> Int -> Word32
    mulPow5DivPow2 Word32
    v (Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1) Int
    j')
              else Word32
    0
          !(Bool
    vvTrailing , Bool
    vuTrailing, Word32
    vw') =
            case () of
              ()
    _ | Int
    q Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Int
    1 Bool -> Bool -> Bool
    && Word32 -> Bool
    forall a. Mantissa a => a -> Bool
    acceptBounds Word32
    v
                    -> (Bool
    True, Word32
    v Word32 -> Word32 -> Word32
    forall a. Num a => a -> a -> a
    - Word32
    u Word32 -> Word32 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word32
    2, Word32
    w') -- mmShift == 1
                | Int
    q Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Int
    1
                    -> (Bool
    True, Bool
    False, Word32
    w' Word32 -> Word32 -> Word32
    forall a. Num a => a -> a -> a
    - Word32
    1)
                | Int
    q Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    31
                    -> (Word32 -> Int -> Bool
    forall a. Mantissa a => a -> Int -> Bool
    multipleOfPowerOf2 Word32
    v (Int
    q Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    1), Bool
    False, Word32
    w')
                | Bool
    otherwise
                    -> (Bool
    False, Bool
    False, Word32
    w')
       in (Word32
    -> Word32 -> Word32 -> Word32 -> Bool -> Bool -> BoundsState Word32
    forall a. a -> a -> a -> a -> Bool -> Bool -> BoundsState a
    BoundsState Word32
    u' Word32
    v' Word32
    vw' Word32
    lastRemoved Bool
    vuTrailing Bool
    vvTrailing, Int -> Int32
    intToInt32 Int
    e10)

    -- | Returns the decimal representation of the given mantissa and exponent of a
    -- 32-bit Float using the ryu algorithm.
    f2d :: Word32 -> Word32 -> FloatingDecimal
    f2d :: Word32 -> Word32 -> FloatingDecimal
    f2d Word32
    m Word32
    e =
      let !mf :: Word32
    mf = if Word32
    e Word32 -> Word32 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word32
    0
                  then Word32
    m
                  else (Word32
    1 Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `unsafeShiftL` Int
    float_mantissa_bits) Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    .|. Word32
    m
          !ef :: Int32
    ef = Int -> Int32
    intToInt32 (Int -> Int32) -> Int -> Int32
    forall a b. (a -> b) -> a -> b
    $ if Word32
    e Word32 -> Word32 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word32
    0
                  then Int
    1 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - (Int
    float_bias Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    float_mantissa_bits)
                  else Word32 -> Int
    word32ToInt Word32
    e Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - (Int
    float_bias Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    float_mantissa_bits)
          !e2 :: Int32
    e2 = Int32
    ef Int32 -> Int32 -> Int32
    forall a. Num a => a -> a -> a
    - Int32
    2
          -- Step 2. 3-tuple (u, v, w) * 2**e2
          !u :: Word32
    u = Word32
    4 Word32 -> Word32 -> Word32
    forall a. Num a => a -> a -> a
    * Word32
    mf Word32 -> Word32 -> Word32
    forall a. Num a => a -> a -> a
    - Word32
    1 Word32 -> Word32 -> Word32
    forall a. Num a => a -> a -> a
    - Bool -> Word32
    boolToWord32 (Word32
    m Word32 -> Word32 -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Word32
    0 Bool -> Bool -> Bool
    || Word32
    e Word32 -> Word32 -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Word32
    1)
          !v :: Word32
    v = Word32
    4 Word32 -> Word32 -> Word32
    forall a. Num a => a -> a -> a
    * Word32
    mf
          !w :: Word32
    w = Word32
    4 Word32 -> Word32 -> Word32
    forall a. Num a => a -> a -> a
    * Word32
    mf Word32 -> Word32 -> Word32
    forall a. Num a => a -> a -> a
    + Word32
    2
          -- Step 3. convert to decimal power base
          !(BoundsState Word32
    state, Int32
    e10) =
            if Int32
    e2 Int32 -> Int32 -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int32
    0
               then Int32 -> Word32 -> Word32 -> Word32 -> (BoundsState Word32, Int32)
    f2dGT Int32
    e2 Word32
    u Word32
    v Word32
    w
               else Int32 -> Word32 -> Word32 -> Word32 -> (BoundsState Word32, Int32)
    f2dLT Int32
    e2 Word32
    u Word32
    v Word32
    w
          -- Step 4: Find the shortest decimal representation in the interval of
          -- valid representations.
          !(Word32
    output, Int32
    removed) =
            let rounded :: BoundsState Word32 -> Word32
    rounded = Bool -> BoundsState Word32 -> Word32
    forall a. Mantissa a => Bool -> BoundsState a -> a
    closestCorrectlyRounded (Word32 -> Bool
    forall a. Mantissa a => a -> Bool
    acceptBounds Word32
    v)
             in (BoundsState Word32 -> Word32)
    -> (BoundsState Word32, Int32) -> (Word32, Int32)
    forall b c d. (b -> c) -> (b, d) -> (c, d)
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> a (b, d) (c, d)
    first BoundsState Word32 -> Word32
    rounded ((BoundsState Word32, Int32) -> (Word32, Int32))
    -> (BoundsState Word32, Int32) -> (Word32, Int32)
    forall a b. (a -> b) -> a -> b
    $ if BoundsState Word32 -> Bool
    forall a. BoundsState a -> Bool
    vvIsTrailingZeros BoundsState Word32
    state Bool -> Bool -> Bool
    || BoundsState Word32 -> Bool
    forall a. BoundsState a -> Bool
    vuIsTrailingZeros BoundsState Word32
    state
               then BoundsState Word32 -> (BoundsState Word32, Int32)
    forall a.
    (Show a, Mantissa a) =>
    BoundsState a -> (BoundsState a, Int32)
    trimTrailing BoundsState Word32
    state
               else BoundsState Word32 -> (BoundsState Word32, Int32)
    forall a. Mantissa a => BoundsState a -> (BoundsState a, Int32)
    trimNoTrailing BoundsState Word32
    state
          !e' :: Int32
    e' = Int32
    e10 Int32 -> Int32 -> Int32
    forall a. Num a => a -> a -> a
    + Int32
    removed
       in Word32 -> Int32 -> FloatingDecimal
    FloatingDecimal Word32
    output Int32
    e'

    -- | Split a Float into (sign, mantissa, exponent)
    breakdown :: Float -> (Bool, Word32, Word32)
    breakdown :: Float -> (Bool, Word32, Word32)
    breakdown Float
    f =
      let bits :: Word32
    bits = Float -> Word32
    castFloatToWord32 Float
    f
          sign :: Bool
    sign = ((Word32
    bits Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `unsafeShiftR` (Int
    float_mantissa_bits Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    float_exponent_bits)) Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    .&. Word32
    1) Word32 -> Word32 -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Word32
    0
          mantissa :: Word32
    mantissa = Word32
    bits Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    .&. Int -> Word32
    forall a. (Bits a, Integral a) => Int -> a
    mask Int
    float_mantissa_bits
          expo :: Word32
    expo = (Word32
    bits Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `unsafeShiftR` Int
    float_mantissa_bits) Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    .&. Int -> Word32
    forall a. (Bits a, Integral a) => Int -> a
    mask Int
    float_exponent_bits
       in (Bool
    sign, Word32
    mantissa, Word32
    expo)

    -- | Dispatches to `f2d` and applies the given formatters
    {-# INLINE f2s' #-}
    f2s' :: (Bool -> Word32 -> Int32 -> a) -> (NonNumbersAndZero -> a) -> Float -> a
    f2s' :: forall a.
    (Bool -> Word32 -> Int32 -> a)
    -> (NonNumbersAndZero -> a) -> Float -> a
    f2s' Bool -> Word32 -> Int32 -> a
    formatter NonNumbersAndZero -> a
    specialFormatter Float
    f =
      let (Bool
    sign, Word32
    mantissa, Word32
    expo) = Float -> (Bool, Word32, Word32)
    breakdown Float
    f
       in if (Word32
    expo Word32 -> Word32 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int -> Word32
    forall a. (Bits a, Integral a) => Int -> a
    mask Int
    float_exponent_bits) Bool -> Bool -> Bool
    || (Word32
    expo Word32 -> Word32 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word32
    0 Bool -> Bool -> Bool
    && Word32
    mantissa Word32 -> Word32 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word32
    0)
             then NonNumbersAndZero -> a
    specialFormatter NonNumbersAndZero
                      { negative :: Bool
    negative=Bool
    sign
                      , exponent_all_one :: Bool
    exponent_all_one=Word32
    expo Word32 -> Word32 -> Bool
    forall a. Ord a => a -> a -> Bool
    > Word32
    0
                      , mantissa_non_zero :: Bool
    mantissa_non_zero=Word32
    mantissa Word32 -> Word32 -> Bool
    forall a. Ord a => a -> a -> Bool
    > Word32
    0 }
             else let FloatingDecimal Word32
    m Int32
    e = Word32 -> Word32 -> FloatingDecimal
    f2d Word32
    mantissa Word32
    expo
                   in Bool -> Word32 -> Int32 -> a
    formatter Bool
    sign Word32
    m Int32
    e

    -- | Render a Float in scientific notation
    f2s :: Float -> Builder
    f2s :: Float -> Builder
    f2s Float
    f = BoundedPrim () -> () -> Builder
    forall a. BoundedPrim a -> a -> Builder
    primBounded ((Bool -> Word32 -> Int32 -> BoundedPrim ())
    -> (NonNumbersAndZero -> BoundedPrim ()) -> Float -> BoundedPrim ()
    forall a.
    (Bool -> Word32 -> Int32 -> a)
    -> (NonNumbersAndZero -> a) -> Float -> a
    f2s' Bool -> Word32 -> Int32 -> BoundedPrim ()
    forall a. Mantissa a => Bool -> a -> Int32 -> BoundedPrim ()
    toCharsScientific NonNumbersAndZero -> BoundedPrim ()
    toCharsNonNumbersAndZero Float
    f) ()

    -- | Returns the decimal representation of a Float. NaN and Infinity will
    -- return `FloatingDecimal 0 0`
    f2Intermediate :: Float -> FloatingDecimal
    f2Intermediate :: Float -> FloatingDecimal
    f2Intermediate = (Bool -> Word32 -> Int32 -> FloatingDecimal)
    -> (NonNumbersAndZero -> FloatingDecimal)
    -> Float
    -> FloatingDecimal
    forall a.
    (Bool -> Word32 -> Int32 -> a)
    -> (NonNumbersAndZero -> a) -> Float -> a
    f2s' ((Word32 -> Int32 -> FloatingDecimal)
    -> Bool -> Word32 -> Int32 -> FloatingDecimal
    forall a b. a -> b -> a
    const Word32 -> Int32 -> FloatingDecimal
    FloatingDecimal) (FloatingDecimal -> NonNumbersAndZero -> FloatingDecimal
    forall a b. a -> b -> a
    const (FloatingDecimal -> NonNumbersAndZero -> FloatingDecimal)
    -> FloatingDecimal -> NonNumbersAndZero -> FloatingDecimal
    forall a b. (a -> b) -> a -> b
    $ Word32 -> Int32 -> FloatingDecimal
    FloatingDecimal Word32
    0 Int32
    0)