{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE BangPatterns, MagicHash, UnboxedTuples #-}
module Data.ByteString.Builder.RealFloat.TableGenerator
( float_pow5_inv_bitcount
, float_pow5_bitcount
, double_pow5_bitcount
, double_pow5_inv_bitcount
, float_max_split
, float_max_inv_split
, double_max_split
, double_max_inv_split
, finv
, fnorm
, splitWord128s
, case64
, case128
) where
import GHC.Float (int2Double)
import Data.Bits
import Data.Word
import Numeric
float_pow5_inv_bitcount :: Int
float_pow5_inv_bitcount :: Int
float_pow5_inv_bitcount = Int
59
float_pow5_bitcount :: Int
float_pow5_bitcount :: Int
float_pow5_bitcount = Int
61
double_pow5_bitcount :: Int
double_pow5_bitcount :: Int
double_pow5_bitcount = Int
125
double_pow5_inv_bitcount :: Int
double_pow5_inv_bitcount :: Int
double_pow5_inv_bitcount = Int
125
blen :: Integer -> Int
blen :: Integer -> Int
blen Integer
0 = Int
0
blen Integer
1 = Int
1
blen Integer
n = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Integer -> Int
blen (Integer
n Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`quot` Integer
2)
finv :: Int -> Int -> Integer
finv :: Int -> Int -> Integer
finv Int
bitcount Int
i =
let p :: Integer
p = Integer
5Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^Int
i
in (Integer
1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` (Integer -> Int
blen Integer
p Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
bitcount)) Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` Integer
p Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
1
fnorm :: Int -> Int -> Integer
fnorm :: Int -> Int -> Integer
fnorm Int
bitcount Int
i =
let p :: Integer
p = Integer
5Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^Int
i
s :: Int
s = Integer -> Int
blen Integer
p Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
bitcount
in if Int
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 then Integer
p Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` (-Int
s) else Integer
p Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
s
splitWord128s :: [Integer] -> [Word64]
splitWord128s :: [Integer] -> [Word64]
splitWord128s [Integer]
li
= [Integer -> Word64
forall a. Num a => Integer -> a
fromInteger Integer
w | Integer
x <- [Integer]
li, Integer
w <- [Integer
x Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
maxWord64, Integer
x Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
64]]
where maxWord64 :: Integer
maxWord64 = Word64 -> Integer
forall a. Integral a => a -> Integer
toInteger (Word64
forall a. Bounded a => a
maxBound :: Word64)
splitWord128 :: Integer -> (Word64,Word64)
splitWord128 :: Integer -> (Word64, Word64)
splitWord128 Integer
x = (Integer -> Word64
forall a. Num a => Integer -> a
fromInteger (Integer
x Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
64), Integer -> Word64
forall a. Num a => Integer -> a
fromInteger (Integer
x Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
maxWord64))
where maxWord64 :: Integer
maxWord64 = Word64 -> Integer
forall a. Integral a => a -> Integer
toInteger (Word64
forall a. Bounded a => a
maxBound :: Word64)
case64 :: (Int -> Integer) -> [Int] -> String
case64 :: (Int -> Integer) -> [Int] -> String
case64 Int -> Integer
f [Int]
range = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" -> 0x" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Integer -> String -> String
forall a. Integral a => a -> String -> String
showHex (Int -> Integer
f Int
i) String
"\n"
| Int
i <- [Int]
range]
case128 :: (Int -> Integer) -> [Int] -> String
case128 :: (Int -> Integer) -> [Int] -> String
case128 Int -> Integer
f [Int]
range = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" -> (0x" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word64 -> String -> String
forall a. Integral a => a -> String -> String
showHex Word64
hi String
"" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", 0x" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word64 -> String -> String
forall a. Integral a => a -> String -> String
showHex Word64
lo String
")\n"
| Int
i <- [Int]
range
, let (Word64
hi,Word64
lo) = Integer -> (Word64, Word64)
splitWord128 (Int -> Integer
f Int
i)
]
get_range :: forall ff. (RealFloat ff) => ff -> (Int, Int)
get_range :: forall ff. RealFloat ff => ff -> (Int, Int)
get_range ff
f =
let (Int
emin, Int
emax) = ff -> (Int, Int)
forall ff. RealFloat ff => ff -> (Int, Int)
floatRange ff
f
mantissaDigits :: Int
mantissaDigits = ff -> Int
forall a. RealFloat a => a -> Int
floatDigits ff
f
emin' :: Int
emin' = Int
emin Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
mantissaDigits Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2
emax' :: Int
emax' = Int
emax Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
mantissaDigits Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2
in ( (-Int
emin') Int -> Int -> Int
forall a. Num a => a -> a -> a
- Double -> Int
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor (Int -> Double
int2Double (-Int
emin') Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double -> Double
forall a. Floating a => a -> a -> a
logBase Double
10 Double
5)
, Double -> Int
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor (Int -> Double
int2Double Int
emax' Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double -> Double
forall a. Floating a => a -> a -> a
logBase Double
10 Double
2))
float_max_split :: Int
float_max_inv_split :: Int
(Int
float_max_split, Int
float_max_inv_split) = Float -> (Int, Int)
forall ff. RealFloat ff => ff -> (Int, Int)
get_range (Float
forall a. HasCallStack => a
undefined :: Float)
double_max_split :: Int
double_max_inv_split :: Int
(Int
double_max_split, Int
double_max_inv_split) =
let (Int
m, Int
mi) = Double -> (Int, Int)
forall ff. RealFloat ff => ff -> (Int, Int)
get_range (Double
forall a. HasCallStack => a
undefined :: Double)
in (Int
m Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1, Int
mi)