{-# LANGUAGE CPP #-}
{-# LANGUAGE RecordWildCards #-}
module Data.ByteString.Builder.RealFloat.Internal
    ( mask
    , NonNumbersAndZero(..)
    , toCharsNonNumbersAndZero
    , decimalLength9
    , decimalLength17
    , Mantissa
    , pow5bits
    , log10pow2
    , log10pow5
    , pow5_factor
    , multipleOfPowerOf5
    , multipleOfPowerOf2
    , acceptBounds
    , BoundsState(..)
    , trimTrailing
    , trimNoTrailing
    , closestCorrectlyRounded
    , toCharsScientific
    
    , fquot10
    , frem10
    , fquot5
    , frem5
    , dquot10
    , dquotRem10
    , dquot5
    , drem5
    , dquot100
    
    , timesWord2
    , castDoubleToWord64
    , castFloatToWord32
    , getWord64At
    , getWord128At
    
    , boolToWord32
    , boolToWord64
    , int32ToInt
    , intToInt32
    , word32ToInt
    , word64ToInt
    , word32ToWord64
    , word64ToWord32
    , module Data.ByteString.Builder.RealFloat.TableGenerator
    ) where
import Control.Monad (foldM)
import Data.Bits (Bits(..), FiniteBits(..))
import Data.ByteString.Internal (c2w)
import Data.ByteString.Builder.Prim.Internal (BoundedPrim, boundedPrim)
import Data.ByteString.Builder.RealFloat.TableGenerator
import Data.ByteString.Utils.ByteOrder
import Data.ByteString.Utils.UnalignedAccess
#if PURE_HASKELL
import qualified Data.ByteString.Internal.Pure as Pure
#else
import Foreign.C.Types
#endif
import Data.Char (ord)
import GHC.Int (Int(..), Int32(..))
import GHC.IO (IO(..), unIO)
import GHC.Prim
import GHC.Ptr (Ptr(..), plusPtr, castPtr)
import GHC.Types (isTrue#)
import GHC.Word (Word8, Word16(..), Word32(..), Word64(..))
import qualified Foreign.Storable as S (poke)
#include <ghcautoconf.h>
#include "MachDeps.h"
#if WORD_SIZE_IN_BITS < 64 && !MIN_VERSION_ghc_prim(0,8,0)
import GHC.IntWord64
#endif
import Data.ByteString.Builder.Prim.Internal.Floating
  (castFloatToWord32, castDoubleToWord64)
{-# INLINABLE mask #-}
mask :: (Bits a, Integral a) => Int -> a
mask :: forall a. (Bits a, Integral a) => Int -> a
mask = (a -> a -> a) -> a -> a -> a
forall a b c. (a -> b -> c) -> b -> a -> c
flip (-) a
1 (a -> a) -> (Int -> a) -> Int -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Int -> a
forall a. Bits a => a -> Int -> a
unsafeShiftL a
1
{-# INLINABLE boolToWord32 #-}
boolToWord32 :: Bool -> Word32
boolToWord32 :: Bool -> Word32
boolToWord32 = Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word32) -> (Bool -> Int) -> Bool -> Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Int
forall a. Enum a => a -> Int
fromEnum
{-# INLINABLE boolToWord64 #-}
boolToWord64 :: Bool -> Word64
boolToWord64 :: Bool -> Word64
boolToWord64 = Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word64) -> (Bool -> Int) -> Bool -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Int
forall a. Enum a => a -> Int
fromEnum
{-# INLINABLE int32ToInt #-}
int32ToInt :: Int32 -> Int
int32ToInt :: Int32 -> Int
int32ToInt = Int32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral
{-# INLINABLE intToInt32 #-}
intToInt32 :: Int -> Int32
intToInt32 :: Int -> Int32
intToInt32 = Int -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral
{-# INLINABLE word32ToInt #-}
word32ToInt :: Word32 -> Int
word32ToInt :: Word32 -> Int
word32ToInt = Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral
{-# INLINABLE word64ToInt #-}
word64ToInt :: Word64 -> Int
word64ToInt :: Word64 -> Int
word64ToInt = Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral
{-# INLINABLE word32ToWord64 #-}
word32ToWord64 :: Word32 -> Word64
word32ToWord64 :: Word32 -> Word64
word32ToWord64 = Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral
{-# INLINABLE word64ToWord32 #-}
word64ToWord32 :: Word64 -> Word32
word64ToWord32 :: Word64 -> Word32
word64ToWord32 = Word64 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral
decimalLength9 :: Word32 -> Int
decimalLength9 :: Word32 -> Int
decimalLength9 Word32
v
  | Word32
v Word32 -> Word32 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word32
100000000 = Int
9
  | Word32
v Word32 -> Word32 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word32
10000000 = Int
8
  | Word32
v Word32 -> Word32 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word32
1000000 = Int
7
  | Word32
v Word32 -> Word32 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word32
100000 = Int
6
  | Word32
v Word32 -> Word32 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word32
10000 = Int
5
  | Word32
v Word32 -> Word32 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word32
1000 = Int
4
  | Word32
v Word32 -> Word32 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word32
100 = Int
3
  | Word32
v Word32 -> Word32 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word32
10 = Int
2
  | Bool
otherwise = Int
1
decimalLength17 :: Word64 -> Int
decimalLength17 :: Word64 -> Int
decimalLength17 Word64
v
  | Word64
v Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word64
10000000000000000 = Int
17
  | Word64
v Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word64
1000000000000000 = Int
16
  | Word64
v Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word64
100000000000000 = Int
15
  | Word64
v Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word64
10000000000000 = Int
14
  | Word64
v Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word64
1000000000000 = Int
13
  | Word64
v Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word64
100000000000 = Int
12
  | Word64
v Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word64
10000000000 = Int
11
  | Word64
v Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word64
1000000000 = Int
10
  | Word64
v Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word64
100000000 = Int
9
  | Word64
v Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word64
10000000 = Int
8
  | Word64
v Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word64
1000000 = Int
7
  | Word64
v Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word64
100000 = Int
6
  | Word64
v Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word64
10000 = Int
5
  | Word64
v Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word64
1000 = Int
4
  | Word64
v Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word64
100 = Int
3
  | Word64
v Word64 -> Word64 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word64
10 = Int
2
  | Bool
otherwise = Int
1
maxEncodedLength :: Int
maxEncodedLength :: Int
maxEncodedLength = Int
32
pokeAll :: String -> Ptr Word8 -> IO (Ptr Word8)
pokeAll :: String -> Ptr Word8 -> IO (Ptr Word8)
pokeAll String
s Ptr Word8
ptr = (Ptr Word8 -> Char -> IO (Ptr Word8))
-> Ptr Word8 -> String -> IO (Ptr Word8)
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM Ptr Word8 -> Char -> IO (Ptr Word8)
forall {b}. Ptr Word8 -> Char -> IO (Ptr b)
pokeOne Ptr Word8
ptr String
s
  where pokeOne :: Ptr Word8 -> Char -> IO (Ptr b)
pokeOne Ptr Word8
p Char
c = Ptr Word8 -> Word8 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
S.poke Ptr Word8
p (Char -> Word8
c2w Char
c) IO () -> IO (Ptr b) -> IO (Ptr b)
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Ptr b -> IO (Ptr b)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Ptr Word8
p Ptr Word8 -> Int -> Ptr b
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
1)
boundString :: String -> BoundedPrim ()
boundString :: String -> BoundedPrim ()
boundString String
s = Int -> (() -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim ()
forall a.
Int -> (a -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim a
boundedPrim Int
maxEncodedLength ((() -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim ())
-> (() -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim ()
forall a b. (a -> b) -> a -> b
$ (Ptr Word8 -> IO (Ptr Word8)) -> () -> Ptr Word8 -> IO (Ptr Word8)
forall a b. a -> b -> a
const (String -> Ptr Word8 -> IO (Ptr Word8)
pokeAll String
s)
data NonNumbersAndZero = NonNumbersAndZero
  { NonNumbersAndZero -> Bool
negative :: Bool
  , NonNumbersAndZero -> Bool
exponent_all_one :: Bool
  , NonNumbersAndZero -> Bool
mantissa_non_zero :: Bool
  }
toCharsNonNumbersAndZero :: NonNumbersAndZero -> BoundedPrim ()
toCharsNonNumbersAndZero :: NonNumbersAndZero -> BoundedPrim ()
toCharsNonNumbersAndZero NonNumbersAndZero{Bool
negative :: NonNumbersAndZero -> Bool
exponent_all_one :: NonNumbersAndZero -> Bool
mantissa_non_zero :: NonNumbersAndZero -> Bool
negative :: Bool
exponent_all_one :: Bool
mantissa_non_zero :: Bool
..}
  | Bool
mantissa_non_zero = String -> BoundedPrim ()
boundString String
"NaN"
  | Bool
exponent_all_one = String -> BoundedPrim ()
boundString (String -> BoundedPrim ()) -> String -> BoundedPrim ()
forall a b. (a -> b) -> a -> b
$ String
signStr String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"Infinity"
  | Bool
otherwise = String -> BoundedPrim ()
boundString (String -> BoundedPrim ()) -> String -> BoundedPrim ()
forall a b. (a -> b) -> a -> b
$ String
signStr String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"0.0e0"
  where signStr :: String
signStr = if Bool
negative then String
"-" else String
""
acceptBounds :: Mantissa a => a -> Bool
acceptBounds :: forall a. Mantissa a => a -> Bool
acceptBounds a
_ = Bool
False
pow5bitsUnboxed :: Int# -> Int#
pow5bitsUnboxed :: Int# -> Int#
pow5bitsUnboxed Int#
e = (Int#
e Int# -> Int# -> Int#
*# Int#
1217359#) Int# -> Int# -> Int#
`uncheckedIShiftRL#` Int#
19# Int# -> Int# -> Int#
+# Int#
1#
log10pow2Unboxed :: Int# -> Int#
log10pow2Unboxed :: Int# -> Int#
log10pow2Unboxed Int#
e = (Int#
e Int# -> Int# -> Int#
*# Int#
78913#) Int# -> Int# -> Int#
`uncheckedIShiftRL#` Int#
18#
log10pow5Unboxed :: Int# -> Int#
log10pow5Unboxed :: Int# -> Int#
log10pow5Unboxed Int#
e = (Int#
e Int# -> Int# -> Int#
*# Int#
732923#) Int# -> Int# -> Int#
`uncheckedIShiftRL#` Int#
20#
pow5bits, log10pow2, log10pow5 :: Int -> Int
pow5bits :: Int -> Int
pow5bits  = (Int# -> Int#) -> Int -> Int
wrapped Int# -> Int#
pow5bitsUnboxed
log10pow2 :: Int -> Int
log10pow2 = (Int# -> Int#) -> Int -> Int
wrapped Int# -> Int#
log10pow2Unboxed
log10pow5 :: Int -> Int
log10pow5 = (Int# -> Int#) -> Int -> Int
wrapped Int# -> Int#
log10pow5Unboxed
fquot10 :: Word32 -> Word32
fquot10 :: Word32 -> Word32
fquot10 Word32
w = Word64 -> Word32
word64ToWord32 ((Word32 -> Word64
word32ToWord64 Word32
w Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
0xCCCCCCCD) Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
35)
frem10 :: Word32 -> Word32
frem10 :: Word32 -> Word32
frem10 Word32
w = Word32
w Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32 -> Word32
fquot10 Word32
w Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
* Word32
10
fquotRem10 :: Word32 -> (Word32, Word32)
fquotRem10 :: Word32 -> (Word32, Word32)
fquotRem10 Word32
w =
  let w' :: Word32
w' = Word32 -> Word32
fquot10 Word32
w
   in (Word32
w', Word32
w Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32 -> Word32
fquot10 Word32
w Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
* Word32
10)
fquot100 :: Word32 -> Word32
fquot100 :: Word32 -> Word32
fquot100 Word32
w = Word64 -> Word32
word64ToWord32 ((Word32 -> Word64
word32ToWord64 Word32
w Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
0x51EB851F) Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
37)
fquotRem10000 :: Word32 -> (Word32, Word32)
fquotRem10000 :: Word32 -> (Word32, Word32)
fquotRem10000 Word32
w =
  let w' :: Word32
w' = Word64 -> Word32
word64ToWord32 ((Word32 -> Word64
word32ToWord64 Word32
w Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
0xD1B71759) Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
45)
    in (Word32
w', Word32
w Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
w' Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
* Word32
10000)
fquot5 :: Word32 -> Word32
fquot5 :: Word32 -> Word32
fquot5 Word32
w = Word64 -> Word32
word64ToWord32 ((Word32 -> Word64
word32ToWord64 Word32
w Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
0xCCCCCCCD) Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
34)
frem5 :: Word32 -> Word32
frem5 :: Word32 -> Word32
frem5 Word32
w = Word32
w Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32 -> Word32
fquot5 Word32
w Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
* Word32
5
dquot10 :: Word64 -> Word64
dquot10 :: Word64 -> Word64
dquot10 Word64
w =
  let !(Word64
rdx, Word64
_) = Word64
w Word64 -> Word64 -> (Word64, Word64)
`timesWord2` Word64
0xCCCCCCCCCCCCCCCD
    in Word64
rdx Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
3
dquot100 :: Word64 -> Word64
dquot100 :: Word64 -> Word64
dquot100 Word64
w =
  let !(Word64
rdx, Word64
_) = (Word64
w Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
2) Word64 -> Word64 -> (Word64, Word64)
`timesWord2` Word64
0x28F5C28F5C28F5C3
    in Word64
rdx Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
2
dquotRem10000 :: Word64 -> (Word64, Word64)
dquotRem10000 :: Word64 -> (Word64, Word64)
dquotRem10000 Word64
w =
  let !(Word64
rdx, Word64
_) = Word64
w Word64 -> Word64 -> (Word64, Word64)
`timesWord2` Word64
0x346DC5D63886594B
      w' :: Word64
w' = Word64
rdx Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
11
   in (Word64
w', Word64
w Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
w' Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
10000)
dquotRem10 :: Word64 -> (Word64, Word64)
dquotRem10 :: Word64 -> (Word64, Word64)
dquotRem10 Word64
w =
  let w' :: Word64
w' = Word64 -> Word64
dquot10 Word64
w
   in (Word64
w', Word64
w Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
w' Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
10)
dquot5 :: Word64 -> Word64
dquot5 :: Word64 -> Word64
dquot5 Word64
w =
  let !(Word64
rdx, Word64
_) = Word64
w Word64 -> Word64 -> (Word64, Word64)
`timesWord2` Word64
0xCCCCCCCCCCCCCCCD
    in Word64
rdx Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
2
drem5 :: Word64 -> Word64
drem5 :: Word64 -> Word64
drem5 Word64
w = Word64
w Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64 -> Word64
dquot5 Word64
w Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
5
dquotRem5 :: Word64 -> (Word64, Word64)
dquotRem5 :: Word64 -> (Word64, Word64)
dquotRem5 Word64
w =
  let w' :: Word64
w' = Word64 -> Word64
dquot5 Word64
w
   in (Word64
w', Word64
w Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
w' Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
5)
wrapped :: (Int# -> Int#) -> Int -> Int
wrapped :: (Int# -> Int#) -> Int -> Int
wrapped Int# -> Int#
f (I# Int#
w) = Int# -> Int
I# (Int# -> Int#
f Int#
w)
#if WORD_SIZE_IN_BITS == 32
packWord64 :: Word# -> Word# -> Word64#
packWord64 hi lo = case hostByteOrder of
  BigEndian ->
    ((wordToWord64# lo) `uncheckedShiftL64#` 32#) `or64#` (wordToWord64# hi)
  LittleEndian ->
    ((wordToWord64# hi) `uncheckedShiftL64#` 32#) `or64#` (wordToWord64# lo)
unpackWord64 :: Word64# -> (# Word#, Word# #)
unpackWord64 w = case hostByteOrder of
  BigEndian ->
    (# word64ToWord# w
     , word64ToWord# (w `uncheckedShiftRL64#` 32#)
     #)
  LittleEndian ->
    (# word64ToWord# (w `uncheckedShiftRL64#` 32#)
     , word64ToWord# w
     #)
plusWord64 :: Word64# -> Word64# -> Word64#
plusWord64 x y =
  let !(# x_h, x_l #) = unpackWord64 x
      !(# y_h, y_l #) = unpackWord64 y
      lo = x_l `plusWord#` y_l
      carry = int2Word# (lo `ltWord#` x_l)
      hi = x_h `plusWord#` y_h `plusWord#` carry
   in packWord64 hi lo
#endif
timesWord2 :: Word64 -> Word64 -> (Word64, Word64)
timesWord2 :: Word64 -> Word64 -> (Word64, Word64)
timesWord2 Word64
a Word64
b =
  let ra :: WORD64
ra = Word64 -> WORD64
forall a. Mantissa a => a -> WORD64
raw Word64
a
      rb :: WORD64
rb = Word64 -> WORD64
forall a. Mantissa a => a -> WORD64
raw Word64
b
#if WORD_SIZE_IN_BITS >= 64
#if __GLASGOW_HASKELL__ < 903
      !(# hi, lo #) = ra `timesWord2#` rb
#else
      !(# Word#
hi_, Word#
lo_ #) = WORD64 -> Word#
word64ToWord# WORD64
ra Word# -> Word# -> (# Word#, Word# #)
`timesWord2#` WORD64 -> Word#
word64ToWord# WORD64
rb
      hi :: WORD64
hi = Word# -> WORD64
wordToWord64# Word#
hi_
      lo :: WORD64
lo = Word# -> WORD64
wordToWord64# Word#
lo_
#endif
#else
      !(# x_h, x_l #) = unpackWord64 ra
      !(# y_h, y_l #) = unpackWord64 rb
      !(# phh_h, phh_l #) = x_h `timesWord2#` y_h
      !(# phl_h, phl_l #) = x_h `timesWord2#` y_l
      !(# plh_h, plh_l #) = x_l `timesWord2#` y_h
      !(# pll_h, pll_l #) = x_l `timesWord2#` y_l
      
      
      
      
      
      
      
      
      
      
      
      
      phh = packWord64 phh_h phh_l
      phl = packWord64 phl_h phl_l
      !(# mh, ml #) = unpackWord64 (phl
        `plusWord64` (wordToWord64# pll_h)
        `plusWord64` (wordToWord64# plh_l))
      hi = phh
        `plusWord64` (wordToWord64# mh)
        `plusWord64` (wordToWord64# plh_h)
      lo = packWord64 ml pll_l
#endif
   in (WORD64 -> Word64
W64# WORD64
hi, WORD64 -> Word64
W64# WORD64
lo)
type WORD64 =
#if WORD_SIZE_IN_BITS < 64 || __GLASGOW_HASKELL__ >= 903
  Word64#
#else
  Word#
#endif
pow5_factor :: WORD64 -> Int# -> Int#
pow5_factor :: WORD64 -> Int# -> Int#
pow5_factor WORD64
w Int#
count =
  let !(W64# WORD64
q, W64# WORD64
r) = Word64 -> (Word64, Word64)
dquotRem5 (WORD64 -> Word64
W64# WORD64
w)
#if WORD_SIZE_IN_BITS >= 64 && __GLASGOW_HASKELL__ < 903
   in case r `eqWord#` 0## of
#else
   in case WORD64
r WORD64 -> WORD64 -> Int#
`eqWord64#` Word# -> WORD64
wordToWord64# Word#
0## of
#endif
        Int#
0# -> Int#
count
        Int#
_  -> WORD64 -> Int# -> Int#
pow5_factor WORD64
q (Int#
count Int# -> Int# -> Int#
+# Int#
1#)
multipleOfPowerOf5 :: Mantissa a => a -> Int -> Bool
multipleOfPowerOf5 :: forall a. Mantissa a => a -> Int -> Bool
multipleOfPowerOf5 a
value (I# Int#
p) = Int# -> Bool
isTrue# (WORD64 -> Int# -> Int#
pow5_factor (a -> WORD64
forall a. Mantissa a => a -> WORD64
raw a
value) Int#
0# Int# -> Int# -> Int#
>=# Int#
p)
multipleOfPowerOf2 :: Mantissa a => a -> Int -> Bool
multipleOfPowerOf2 :: forall a. Mantissa a => a -> Int -> Bool
multipleOfPowerOf2 a
value Int
p = (a
value a -> a -> a
forall a. Bits a => a -> a -> a
.&. Int -> a
forall a. (Bits a, Integral a) => Int -> a
mask Int
p) a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0
class (FiniteBits a, Integral a) => Mantissa a where
  
  
  unsafeRaw :: a -> Word#
  raw :: a -> WORD64
  decimalLength :: a -> Int
  boolToWord :: Bool -> a
  quotRem10 :: a -> (a, a)
  quot10  :: a -> a
  quot100 :: a -> a
  quotRem100 :: a -> (a, a)
  quotRem10000 :: a -> (a, a)
instance Mantissa Word32 where
#if __GLASGOW_HASKELL__ >= 902
  unsafeRaw :: Word32 -> Word#
unsafeRaw (W32# Word32#
w) = Word32# -> Word#
word32ToWord# Word32#
w
#else
  unsafeRaw (W32# w) = w
#endif
#if WORD_SIZE_IN_BITS >= 64 && __GLASGOW_HASKELL__ < 903
  raw = unsafeRaw
#else
  raw :: Word32 -> WORD64
raw Word32
w = Word# -> WORD64
wordToWord64# (Word32 -> Word#
forall a. Mantissa a => a -> Word#
unsafeRaw Word32
w)
#endif
  decimalLength :: Word32 -> Int
decimalLength = Word32 -> Int
decimalLength9
  boolToWord :: Bool -> Word32
boolToWord = Bool -> Word32
boolToWord32
  {-# INLINE quotRem10 #-}
  quotRem10 :: Word32 -> (Word32, Word32)
quotRem10 = Word32 -> (Word32, Word32)
fquotRem10
  {-# INLINE quot10 #-}
  quot10 :: Word32 -> Word32
quot10 = Word32 -> Word32
fquot10
  {-# INLINE quot100 #-}
  quot100 :: Word32 -> Word32
quot100 = Word32 -> Word32
fquot100
  quotRem100 :: Word32 -> (Word32, Word32)
quotRem100 Word32
w =
    let w' :: Word32
w' = Word32 -> Word32
fquot100 Word32
w
      in (Word32
w', (Word32
w Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
w' Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
* Word32
100))
  quotRem10000 :: Word32 -> (Word32, Word32)
quotRem10000 = Word32 -> (Word32, Word32)
fquotRem10000
instance Mantissa Word64 where
#if WORD_SIZE_IN_BITS >= 64 && __GLASGOW_HASKELL__ < 903
  unsafeRaw (W64# w) = w
#else
  unsafeRaw :: Word64 -> Word#
unsafeRaw (W64# WORD64
w) = WORD64 -> Word#
word64ToWord# WORD64
w
#endif
  raw :: Word64 -> WORD64
raw (W64# WORD64
w) = WORD64
w
  decimalLength :: Word64 -> Int
decimalLength = Word64 -> Int
decimalLength17
  boolToWord :: Bool -> Word64
boolToWord = Bool -> Word64
boolToWord64
  {-# INLINE quotRem10 #-}
  quotRem10 :: Word64 -> (Word64, Word64)
quotRem10 = Word64 -> (Word64, Word64)
dquotRem10
  {-# INLINE quot10 #-}
  quot10 :: Word64 -> Word64
quot10 = Word64 -> Word64
dquot10
  {-# INLINE quot100 #-}
  quot100 :: Word64 -> Word64
quot100 = Word64 -> Word64
dquot100
  quotRem100 :: Word64 -> (Word64, Word64)
quotRem100 Word64
w =
    let w' :: Word64
w' = Word64 -> Word64
dquot100 Word64
w
     in (Word64
w', (Word64
w Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
w' Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
100))
  quotRem10000 :: Word64 -> (Word64, Word64)
quotRem10000 = Word64 -> (Word64, Word64)
dquotRem10000
data BoundsState a = BoundsState
    { forall a. BoundsState a -> a
vu :: !a
    , forall a. BoundsState a -> a
vv :: !a
    , forall a. BoundsState a -> a
vw :: !a
    , forall a. BoundsState a -> a
lastRemovedDigit :: !a
    , forall a. BoundsState a -> Bool
vuIsTrailingZeros :: !Bool
    , forall a. BoundsState a -> Bool
vvIsTrailingZeros :: !Bool
    }
trimTrailing :: (Show a, Mantissa a) => BoundsState a -> (BoundsState a, Int32)
trimTrailing :: forall a.
(Show a, Mantissa a) =>
BoundsState a -> (BoundsState a, Int32)
trimTrailing !BoundsState a
initial = (BoundsState a
res, Int32
r Int32 -> Int32 -> Int32
forall a. Num a => a -> a -> a
+ Int32
r')
  where
    !(BoundsState a
d', Int32
r) = BoundsState a -> (BoundsState a, Int32)
forall {a} {b}.
(Mantissa a, Num b) =>
BoundsState a -> (BoundsState a, b)
trimTrailing' BoundsState a
initial
    !(BoundsState a
d'', Int32
r') = if BoundsState a -> Bool
forall a. BoundsState a -> Bool
vuIsTrailingZeros BoundsState a
d' then BoundsState a -> (BoundsState a, Int32)
forall {a} {b}.
(Mantissa a, Num b) =>
BoundsState a -> (BoundsState a, b)
trimTrailing'' BoundsState a
d' else (BoundsState a
d', Int32
0)
    res :: BoundsState a
res = if BoundsState a -> Bool
forall a. BoundsState a -> Bool
vvIsTrailingZeros BoundsState a
d'' Bool -> Bool -> Bool
&& BoundsState a -> a
forall a. BoundsState a -> a
lastRemovedDigit BoundsState a
d'' a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
5 Bool -> Bool -> Bool
&& BoundsState a -> a
forall a. BoundsState a -> a
vv BoundsState a
d'' a -> a -> a
forall a. Integral a => a -> a -> a
`rem` a
2 a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0
             
             then BoundsState a
d''
             else BoundsState a
d''
    trimTrailing' :: BoundsState a -> (BoundsState a, b)
trimTrailing' !BoundsState a
d
      | a
vw' a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
vu' =
         (b -> b) -> (BoundsState a, b) -> (BoundsState a, b)
forall a b. (a -> b) -> (BoundsState a, a) -> (BoundsState a, b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (b -> b -> b
forall a. Num a => a -> a -> a
(+) b
1) ((BoundsState a, b) -> (BoundsState a, b))
-> (BoundsState a -> (BoundsState a, b))
-> BoundsState a
-> (BoundsState a, b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BoundsState a -> (BoundsState a, b)
trimTrailing' (BoundsState a -> (BoundsState a, b))
-> BoundsState a -> (BoundsState a, b)
forall a b. (a -> b) -> a -> b
$
          BoundsState a
d { vu = vu'
            , vv = vv'
            , vw = vw'
            , lastRemovedDigit = vvRem
            , vuIsTrailingZeros = vuIsTrailingZeros d && vuRem == 0
            , vvIsTrailingZeros = vvIsTrailingZeros d && lastRemovedDigit d == 0
            }
      | Bool
otherwise = (BoundsState a
d, b
0)
      where
        !(a
vv', a
vvRem) = a -> (a, a)
forall a. Mantissa a => a -> (a, a)
quotRem10 (a -> (a, a)) -> a -> (a, a)
forall a b. (a -> b) -> a -> b
$ BoundsState a -> a
forall a. BoundsState a -> a
vv BoundsState a
d
        !(a
vu', a
vuRem) = a -> (a, a)
forall a. Mantissa a => a -> (a, a)
quotRem10 (a -> (a, a)) -> a -> (a, a)
forall a b. (a -> b) -> a -> b
$ BoundsState a -> a
forall a. BoundsState a -> a
vu BoundsState a
d
        !(a
vw', a
_    ) = a -> (a, a)
forall a. Mantissa a => a -> (a, a)
quotRem10 (a -> (a, a)) -> a -> (a, a)
forall a b. (a -> b) -> a -> b
$ BoundsState a -> a
forall a. BoundsState a -> a
vw BoundsState a
d
    trimTrailing'' :: BoundsState a -> (BoundsState a, b)
trimTrailing'' !BoundsState a
d
      | a
vuRem a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0 =
         (b -> b) -> (BoundsState a, b) -> (BoundsState a, b)
forall a b. (a -> b) -> (BoundsState a, a) -> (BoundsState a, b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (b -> b -> b
forall a. Num a => a -> a -> a
(+) b
1) ((BoundsState a, b) -> (BoundsState a, b))
-> (BoundsState a -> (BoundsState a, b))
-> BoundsState a
-> (BoundsState a, b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BoundsState a -> (BoundsState a, b)
trimTrailing'' (BoundsState a -> (BoundsState a, b))
-> BoundsState a -> (BoundsState a, b)
forall a b. (a -> b) -> a -> b
$
          BoundsState a
d { vu = vu'
            , vv = vv'
            , vw = vw'
            , lastRemovedDigit = vvRem
            , vvIsTrailingZeros = vvIsTrailingZeros d && lastRemovedDigit d == 0
            }
      | Bool
otherwise = (BoundsState a
d, b
0)
      where
        !(a
vu', a
vuRem) = a -> (a, a)
forall a. Mantissa a => a -> (a, a)
quotRem10 (a -> (a, a)) -> a -> (a, a)
forall a b. (a -> b) -> a -> b
$ BoundsState a -> a
forall a. BoundsState a -> a
vu BoundsState a
d
        !(a
vv', a
vvRem) = a -> (a, a)
forall a. Mantissa a => a -> (a, a)
quotRem10 (a -> (a, a)) -> a -> (a, a)
forall a b. (a -> b) -> a -> b
$ BoundsState a -> a
forall a. BoundsState a -> a
vv BoundsState a
d
        !(a
vw', a
_    ) = a -> (a, a)
forall a. Mantissa a => a -> (a, a)
quotRem10 (a -> (a, a)) -> a -> (a, a)
forall a b. (a -> b) -> a -> b
$ BoundsState a -> a
forall a. BoundsState a -> a
vw BoundsState a
d
trimNoTrailing :: Mantissa a => BoundsState a -> (BoundsState a, Int32)
trimNoTrailing :: forall a. Mantissa a => BoundsState a -> (BoundsState a, Int32)
trimNoTrailing !(BoundsState a
u a
v a
w a
ld Bool
_ Bool
_) =
  (a -> a -> a -> a -> Bool -> Bool -> BoundsState a
forall a. a -> a -> a -> a -> Bool -> Bool -> BoundsState a
BoundsState a
ru' a
rv' a
0 a
ld' Bool
False Bool
False, Int32
c)
  where
    !(a
ru', a
rv', a
ld', Int32
c) = a -> a -> a -> a -> Int32 -> (a, a, a, Int32)
forall {a} {c} {d}.
(Mantissa a, Mantissa c, Num d) =>
a -> c -> a -> c -> d -> (a, c, c, d)
trimNoTrailing' a
u a
v a
w a
ld Int32
0
    trimNoTrailing' :: a -> c -> a -> c -> d -> (a, c, c, d)
trimNoTrailing' a
u' c
v' a
w' c
lastRemoved d
count
      
      
      
      
      | a
vw' a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
vu' =
          a -> c -> a -> c -> d -> (a, c, c, d)
trimNoTrailing'' a
vu' c
vv' a
vw' (c -> c
forall a. Mantissa a => a -> a
quot10 (c
v' c -> c -> c
forall a. Num a => a -> a -> a
- (c
vv' c -> c -> c
forall a. Num a => a -> a -> a
* c
100))) (d
count d -> d -> d
forall a. Num a => a -> a -> a
+ d
2)
      | Bool
otherwise =
          a -> c -> a -> c -> d -> (a, c, c, d)
trimNoTrailing'' a
u' c
v' a
w' c
lastRemoved d
count
      where
        !vw' :: a
vw' = a -> a
forall a. Mantissa a => a -> a
quot100 a
w'
        !vu' :: a
vu' = a -> a
forall a. Mantissa a => a -> a
quot100 a
u'
        !vv' :: c
vv' = c -> c
forall a. Mantissa a => a -> a
quot100 c
v'
    trimNoTrailing'' :: a -> c -> a -> c -> d -> (a, c, c, d)
trimNoTrailing'' a
u' c
v' a
w' c
lastRemoved d
count
      | a
vw' a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
vu' = a -> c -> a -> c -> d -> (a, c, c, d)
trimNoTrailing' a
vu' c
vv' a
vw' c
lastRemoved' (d
count d -> d -> d
forall a. Num a => a -> a -> a
+ d
1)
      | Bool
otherwise = (a
u', c
v', c
lastRemoved, d
count)
      where
        !(c
vv', c
lastRemoved') = c -> (c, c)
forall a. Mantissa a => a -> (a, a)
quotRem10 c
v'
        !vu' :: a
vu' = a -> a
forall a. Mantissa a => a -> a
quot10 a
u'
        !vw' :: a
vw' = a -> a
forall a. Mantissa a => a -> a
quot10 a
w'
{-# INLINE closestCorrectlyRounded #-}
closestCorrectlyRounded :: Mantissa a => Bool -> BoundsState a -> a
closestCorrectlyRounded :: forall a. Mantissa a => Bool -> BoundsState a -> a
closestCorrectlyRounded Bool
acceptBound BoundsState a
s = BoundsState a -> a
forall a. BoundsState a -> a
vv BoundsState a
s a -> a -> a
forall a. Num a => a -> a -> a
+ Bool -> a
forall a. Mantissa a => Bool -> a
boolToWord Bool
roundUp
  where
    outsideBounds :: Bool
outsideBounds = Bool -> Bool
not (BoundsState a -> Bool
forall a. BoundsState a -> Bool
vuIsTrailingZeros BoundsState a
s) Bool -> Bool -> Bool
|| Bool -> Bool
not Bool
acceptBound
    roundUp :: Bool
roundUp = (BoundsState a -> a
forall a. BoundsState a -> a
vv BoundsState a
s a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== BoundsState a -> a
forall a. BoundsState a -> a
vu BoundsState a
s Bool -> Bool -> Bool
&& Bool
outsideBounds) Bool -> Bool -> Bool
|| BoundsState a -> a
forall a. BoundsState a -> a
lastRemovedDigit BoundsState a
s a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
5
asciiRaw :: Int -> Word#
asciiRaw :: Int -> Word#
asciiRaw (I# Int#
i) = Int# -> Word#
int2Word# Int#
i
asciiZero :: Int
asciiZero :: Int
asciiZero = Char -> Int
ord Char
'0'
asciiDot :: Int
asciiDot :: Int
asciiDot = Char -> Int
ord Char
'.'
asciiMinus :: Int
asciiMinus :: Int
asciiMinus = Char -> Int
ord Char
'-'
ascii_e :: Int
ascii_e :: Int
ascii_e = Char -> Int
ord Char
'e'
toAscii :: Word# -> Word#
toAscii :: Word# -> Word#
toAscii Word#
a = Word#
a Word# -> Word# -> Word#
`plusWord#` Int -> Word#
asciiRaw Int
asciiZero
{-# INLINE getWord64At #-}
getWord64At :: Ptr Word64 -> Int -> Word64
getWord64At :: Ptr Word64 -> Int -> Word64
getWord64At (Ptr Addr#
arr) (I# Int#
i) = WORD64 -> Word64
W64# (Addr# -> Int# -> WORD64
indexWord64OffAddr# Addr#
arr Int#
i)
{-# INLINE getWord128At #-}
getWord128At :: Ptr Word64 -> Int -> (Word64, Word64)
getWord128At :: Ptr Word64 -> Int -> (Word64, Word64)
getWord128At (Ptr Addr#
arr) (I# Int#
i) = let
  !hi :: Word64
hi = WORD64 -> Word64
W64# (Addr# -> Int# -> WORD64
indexWord64OffAddr# Addr#
arr (Int#
i Int# -> Int# -> Int#
*# Int#
2# Int# -> Int# -> Int#
+# Int#
1#))
  !lo :: Word64
lo = WORD64 -> Word64
W64# (Addr# -> Int# -> WORD64
indexWord64OffAddr# Addr#
arr (Int#
i Int# -> Int# -> Int#
*# Int#
2#))
  in (Word64
hi, Word64
lo)
packWord16 :: Word# -> Word# -> Word#
packWord16 :: Word# -> Word# -> Word#
packWord16 Word#
l Word#
h = case ByteOrder
hostByteOrder of
  ByteOrder
BigEndian ->
    (Word#
h Word# -> Int# -> Word#
`uncheckedShiftL#` Int#
8#) Word# -> Word# -> Word#
`or#` Word#
l
  ByteOrder
LittleEndian ->
    (Word#
l Word# -> Int# -> Word#
`uncheckedShiftL#` Int#
8#) Word# -> Word# -> Word#
`or#` Word#
h
unpackWord16 :: Word# -> (# Word#, Word# #)
unpackWord16 :: Word# -> (# Word#, Word# #)
unpackWord16 Word#
w = case ByteOrder
hostByteOrder of
  ByteOrder
BigEndian ->
    (# Word#
w Word# -> Word# -> Word#
`and#` Word#
0xff##, Word#
w Word# -> Int# -> Word#
`uncheckedShiftRL#` Int#
8# #)
  ByteOrder
LittleEndian ->
    (# Word#
w Word# -> Int# -> Word#
`uncheckedShiftRL#` Int#
8#, Word#
w Word# -> Word# -> Word#
`and#` Word#
0xff## #)
digit_table :: Ptr Word16
digit_table :: Ptr Word16
digit_table =
#if PURE_HASKELL
  castPtr Pure.digit_pairs_table
#else
  Ptr CChar -> Ptr Word16
forall a b. Ptr a -> Ptr b
castPtr Ptr CChar
c_digit_pairs_table
foreign import ccall "&hs_bytestring_digit_pairs_table"
  c_digit_pairs_table :: Ptr CChar
#endif
unsafeAt :: Ptr Word16 -> Int# -> Word#
unsafeAt :: Ptr Word16 -> Int# -> Word#
unsafeAt (Ptr Addr#
a) Int#
i =
#if __GLASGOW_HASKELL__ >= 902
    Word16# -> Word#
word16ToWord# (Addr# -> Int# -> Word16#
indexWord16OffAddr# Addr#
a Int#
i)
#else
    indexWord16OffAddr# a i
#endif
copyWord16 :: Word# -> Addr# -> State# RealWorld -> State# RealWorld
copyWord16 :: Word# -> Addr# -> State# RealWorld -> State# RealWorld
copyWord16 Word#
w Addr#
a State# RealWorld
s = let
#if __GLASGOW_HASKELL__ >= 902
  w16 :: Word16#
w16 = Word# -> Word16#
wordToWord16# Word#
w
#else
  w16 = w
#endif
  in  case IO () -> State# RealWorld -> (# State# RealWorld, () #)
forall a. IO a -> State# RealWorld -> (# State# RealWorld, a #)
unIO (Word16 -> Ptr Word8 -> IO ()
unalignedWriteU16 (Word16# -> Word16
W16# Word16#
w16) (Addr# -> Ptr Word8
forall a. Addr# -> Ptr a
Ptr Addr#
a)) State# RealWorld
s of
  (# State# RealWorld
s', ()
_ #) -> State# RealWorld
s'
poke :: Addr# -> Word# -> State# d -> State# d
poke :: forall d. Addr# -> Word# -> State# d -> State# d
poke Addr#
a Word#
w State# d
s =
#if __GLASGOW_HASKELL__ >= 902
    Addr# -> Int# -> Word8# -> State# d -> State# d
forall d. Addr# -> Int# -> Word8# -> State# d -> State# d
writeWord8OffAddr# Addr#
a Int#
0# (Word# -> Word8#
wordToWord8# Word#
w) State# d
s
#else
    writeWord8OffAddr# a 0# w s
#endif
{-# SPECIALIZE writeMantissa :: Addr# -> Int# -> Word32 -> State# RealWorld -> (# Addr#, State# RealWorld #) #-}
{-# SPECIALIZE writeMantissa :: Addr# -> Int# -> Word64 -> State# RealWorld -> (# Addr#, State# RealWorld #) #-}
writeMantissa :: forall a. (Mantissa a) => Addr# -> Int# -> a -> State# RealWorld -> (# Addr#, State# RealWorld #)
writeMantissa :: forall a.
Mantissa a =>
Addr#
-> Int# -> a -> State# RealWorld -> (# Addr#, State# RealWorld #)
writeMantissa Addr#
ptr Int#
olength = Addr# -> a -> State# RealWorld -> (# Addr#, State# RealWorld #)
forall {a}.
Mantissa a =>
Addr# -> a -> State# RealWorld -> (# Addr#, State# RealWorld #)
go (Addr#
ptr Addr# -> Int# -> Addr#
`plusAddr#` Int#
olength)
  where
    go :: Addr# -> a -> State# RealWorld -> (# Addr#, State# RealWorld #)
go Addr#
p a
mantissa State# RealWorld
s1
      | a
mantissa a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
10000 =
          let !(a
m', a
c) = a -> (a, a)
forall a. Mantissa a => a -> (a, a)
quotRem10000 a
mantissa
              !(a
c1, a
c0) = a -> (a, a)
forall a. Mantissa a => a -> (a, a)
quotRem100 a
c
              s2 :: State# RealWorld
s2 = Word# -> Addr# -> State# RealWorld -> State# RealWorld
copyWord16 (Ptr Word16
digit_table Ptr Word16 -> Int# -> Word#
`unsafeAt` Word# -> Int#
word2Int# (a -> Word#
forall a. Mantissa a => a -> Word#
unsafeRaw a
c0)) (Addr#
p Addr# -> Int# -> Addr#
`plusAddr#` (Int#
-1#)) State# RealWorld
s1
              s3 :: State# RealWorld
s3 = Word# -> Addr# -> State# RealWorld -> State# RealWorld
copyWord16 (Ptr Word16
digit_table Ptr Word16 -> Int# -> Word#
`unsafeAt` Word# -> Int#
word2Int# (a -> Word#
forall a. Mantissa a => a -> Word#
unsafeRaw a
c1)) (Addr#
p Addr# -> Int# -> Addr#
`plusAddr#` (Int#
-3#)) State# RealWorld
s2
           in Addr# -> a -> State# RealWorld -> (# Addr#, State# RealWorld #)
go (Addr#
p Addr# -> Int# -> Addr#
`plusAddr#` (Int#
-4#)) a
m' State# RealWorld
s3
      | a
mantissa a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
100 =
          let !(a
m', a
c) = a -> (a, a)
forall a. Mantissa a => a -> (a, a)
quotRem100 a
mantissa
              s2 :: State# RealWorld
s2 = Word# -> Addr# -> State# RealWorld -> State# RealWorld
copyWord16 (Ptr Word16
digit_table Ptr Word16 -> Int# -> Word#
`unsafeAt` Word# -> Int#
word2Int# (a -> Word#
forall a. Mantissa a => a -> Word#
unsafeRaw a
c)) (Addr#
p Addr# -> Int# -> Addr#
`plusAddr#` (Int#
-1#)) State# RealWorld
s1
           in a -> State# RealWorld -> (# Addr#, State# RealWorld #)
forall {a}.
Mantissa a =>
a -> State# RealWorld -> (# Addr#, State# RealWorld #)
finalize a
m' State# RealWorld
s2
      | Bool
otherwise = a -> State# RealWorld -> (# Addr#, State# RealWorld #)
forall {a}.
Mantissa a =>
a -> State# RealWorld -> (# Addr#, State# RealWorld #)
finalize a
mantissa State# RealWorld
s1
    finalize :: a -> State# RealWorld -> (# Addr#, State# RealWorld #)
finalize a
mantissa State# RealWorld
s1
      | a
mantissa a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
10 =
        let !bs :: Word#
bs = Ptr Word16
digit_table Ptr Word16 -> Int# -> Word#
`unsafeAt` Word# -> Int#
word2Int# (a -> Word#
forall a. Mantissa a => a -> Word#
unsafeRaw a
mantissa)
            !(# Word#
lsb, Word#
msb #) = Word# -> (# Word#, Word# #)
unpackWord16 Word#
bs
            s2 :: State# RealWorld
s2 = Addr# -> Word# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> Word# -> State# d -> State# d
poke (Addr#
ptr Addr# -> Int# -> Addr#
`plusAddr#` Int#
2#) Word#
lsb State# RealWorld
s1
            s3 :: State# RealWorld
s3 = Addr# -> Word# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> Word# -> State# d -> State# d
poke (Addr#
ptr Addr# -> Int# -> Addr#
`plusAddr#` Int#
1#) (Int -> Word#
asciiRaw Int
asciiDot) State# RealWorld
s2
            s4 :: State# RealWorld
s4 = Addr# -> Word# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> Word# -> State# d -> State# d
poke Addr#
ptr Word#
msb State# RealWorld
s3
           in (# Addr#
ptr Addr# -> Int# -> Addr#
`plusAddr#` (Int#
olength Int# -> Int# -> Int#
+# Int#
1#), State# RealWorld
s4 #)
      | (Int# -> Int
I# Int#
olength) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1 =
          let s2 :: State# RealWorld
s2 = Word# -> Addr# -> State# RealWorld -> State# RealWorld
copyWord16 (Word# -> Word# -> Word#
packWord16 (Int -> Word#
asciiRaw Int
asciiDot) (Word# -> Word#
toAscii (a -> Word#
forall a. Mantissa a => a -> Word#
unsafeRaw a
mantissa))) Addr#
ptr State# RealWorld
s1
           in (# Addr#
ptr Addr# -> Int# -> Addr#
`plusAddr#` (Int#
olength Int# -> Int# -> Int#
+# Int#
1#), State# RealWorld
s2 #)
      | Bool
otherwise =
          let s2 :: State# RealWorld
s2 = Addr# -> Word# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> Word# -> State# d -> State# d
poke (Addr#
ptr Addr# -> Int# -> Addr#
`plusAddr#` Int#
2#) (Int -> Word#
asciiRaw Int
asciiZero) State# RealWorld
s1
              s3 :: State# RealWorld
s3 = Addr# -> Word# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> Word# -> State# d -> State# d
poke (Addr#
ptr Addr# -> Int# -> Addr#
`plusAddr#` Int#
1#) (Int -> Word#
asciiRaw Int
asciiDot) State# RealWorld
s2
              s4 :: State# RealWorld
s4 = Addr# -> Word# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> Word# -> State# d -> State# d
poke Addr#
ptr (Word# -> Word#
toAscii (a -> Word#
forall a. Mantissa a => a -> Word#
unsafeRaw a
mantissa)) State# RealWorld
s3
           in (# Addr#
ptr Addr# -> Int# -> Addr#
`plusAddr#` Int#
3#, State# RealWorld
s4 #)
writeExponent :: Addr# -> Int32 -> State# RealWorld -> (# Addr#, State# RealWorld #)
writeExponent :: Addr# -> Int32 -> State# RealWorld -> (# Addr#, State# RealWorld #)
writeExponent Addr#
ptr !Int32
expo State# RealWorld
s1
  | Int32
expo Int32 -> Int32 -> Bool
forall a. Ord a => a -> a -> Bool
>= Int32
100 =
      let !(Word32
e1, Word32
e0) = Word32 -> (Word32, Word32)
fquotRem10 (Int32 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
expo) 
          s2 :: State# RealWorld
s2 = Word# -> Addr# -> State# RealWorld -> State# RealWorld
copyWord16 (Ptr Word16
digit_table Ptr Word16 -> Int# -> Word#
`unsafeAt` Word# -> Int#
word2Int# (Word32 -> Word#
forall a. Mantissa a => a -> Word#
unsafeRaw Word32
e1)) Addr#
ptr State# RealWorld
s1
          s3 :: State# RealWorld
s3 = Addr# -> Word# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> Word# -> State# d -> State# d
poke (Addr#
ptr Addr# -> Int# -> Addr#
`plusAddr#` Int#
2#) (Word# -> Word#
toAscii (Word32 -> Word#
forall a. Mantissa a => a -> Word#
unsafeRaw Word32
e0)) State# RealWorld
s2
       in (# Addr#
ptr Addr# -> Int# -> Addr#
`plusAddr#` Int#
3#, State# RealWorld
s3 #)
  | Int32
expo Int32 -> Int32 -> Bool
forall a. Ord a => a -> a -> Bool
>= Int32
10 =
      let s2 :: State# RealWorld
s2 = Word# -> Addr# -> State# RealWorld -> State# RealWorld
copyWord16 (Ptr Word16
digit_table Ptr Word16 -> Int# -> Word#
`unsafeAt` Int#
e) Addr#
ptr State# RealWorld
s1
       in (# Addr#
ptr Addr# -> Int# -> Addr#
`plusAddr#` Int#
2#, State# RealWorld
s2 #)
  | Bool
otherwise =
      let s2 :: State# RealWorld
s2 = Addr# -> Word# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> Word# -> State# d -> State# d
poke Addr#
ptr (Word# -> Word#
toAscii (Int# -> Word#
int2Word# Int#
e)) State# RealWorld
s1
       in (# Addr#
ptr Addr# -> Int# -> Addr#
`plusAddr#` Int#
1#, State# RealWorld
s2 #)
  where !(I# Int#
e) = Int32 -> Int
int32ToInt Int32
expo
writeSign :: Addr# -> Bool -> State# d -> (# Addr#, State# d #)
writeSign :: forall d. Addr# -> Bool -> State# d -> (# Addr#, State# d #)
writeSign Addr#
ptr Bool
True State# d
s1 =
  let s2 :: State# d
s2 = Addr# -> Word# -> State# d -> State# d
forall d. Addr# -> Word# -> State# d -> State# d
poke Addr#
ptr (Int -> Word#
asciiRaw Int
asciiMinus) State# d
s1
   in (# Addr#
ptr Addr# -> Int# -> Addr#
`plusAddr#` Int#
1#, State# d
s2 #)
writeSign Addr#
ptr Bool
False State# d
s = (# Addr#
ptr, State# d
s #)
{-# INLINABLE toCharsScientific #-}
{-# SPECIALIZE toCharsScientific :: Bool -> Word32 -> Int32 -> BoundedPrim () #-}
{-# SPECIALIZE toCharsScientific :: Bool -> Word64 -> Int32 -> BoundedPrim () #-}
toCharsScientific :: (Mantissa a) => Bool -> a -> Int32 -> BoundedPrim ()
 !Bool
sign !a
mantissa !Int32
expo = Int -> (() -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim ()
forall a.
Int -> (a -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim a
boundedPrim Int
maxEncodedLength ((() -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim ())
-> (() -> Ptr Word8 -> IO (Ptr Word8)) -> BoundedPrim ()
forall a b. (a -> b) -> a -> b
$ \()
_ !(Ptr Addr#
p0)-> do
  let !olength :: Int
olength@(I# Int#
ol) = a -> Int
forall a. Mantissa a => a -> Int
decimalLength a
mantissa
      !expo' :: Int32
expo' = Int32
expo Int32 -> Int32 -> Int32
forall a. Num a => a -> a -> a
+ Int -> Int32
intToInt32 Int
olength Int32 -> Int32 -> Int32
forall a. Num a => a -> a -> a
- Int32
1
  (State# RealWorld -> (# State# RealWorld, Ptr Word8 #))
-> IO (Ptr Word8)
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, Ptr Word8 #))
 -> IO (Ptr Word8))
-> (State# RealWorld -> (# State# RealWorld, Ptr Word8 #))
-> IO (Ptr Word8)
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s1 ->
    let !(# Addr#
p1, State# RealWorld
s2 #) = Addr# -> Bool -> State# RealWorld -> (# Addr#, State# RealWorld #)
forall d. Addr# -> Bool -> State# d -> (# Addr#, State# d #)
writeSign Addr#
p0 Bool
sign State# RealWorld
s1
        !(# Addr#
p2, State# RealWorld
s3 #) = Addr#
-> Int# -> a -> State# RealWorld -> (# Addr#, State# RealWorld #)
forall a.
Mantissa a =>
Addr#
-> Int# -> a -> State# RealWorld -> (# Addr#, State# RealWorld #)
writeMantissa Addr#
p1 Int#
ol a
mantissa State# RealWorld
s2
        s4 :: State# RealWorld
s4 = Addr# -> Word# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> Word# -> State# d -> State# d
poke Addr#
p2 (Int -> Word#
asciiRaw Int
ascii_e) State# RealWorld
s3
        !(# Addr#
p3, State# RealWorld
s5 #) = Addr# -> Bool -> State# RealWorld -> (# Addr#, State# RealWorld #)
forall d. Addr# -> Bool -> State# d -> (# Addr#, State# d #)
writeSign (Addr#
p2 Addr# -> Int# -> Addr#
`plusAddr#` Int#
1#) (Int32
expo' Int32 -> Int32 -> Bool
forall a. Ord a => a -> a -> Bool
< Int32
0) State# RealWorld
s4
        !(# Addr#
p4, State# RealWorld
s6 #) = Addr# -> Int32 -> State# RealWorld -> (# Addr#, State# RealWorld #)
writeExponent Addr#
p3 (Int32 -> Int32
forall a. Num a => a -> a
abs Int32
expo') State# RealWorld
s5
     in (# State# RealWorld
s6, (Addr# -> Ptr Word8
forall a. Addr# -> Ptr a
Ptr Addr#
p4) #)