{-# LANGUAGE CPP, OverloadedStrings #-}
#if __GLASGOW_HASKELL__ >= 702
{-# LANGUAGE Trustworthy #-}
#endif
module Data.Text.Lazy.Builder.RealFloat
(
FPFormat(..)
, realFloat
, formatRealFloat
) where
import Data.Array.Base (unsafeAt)
import Data.Array.IArray
import Data.Text.Internal.Builder.Functions ((<>), i2d)
import Data.Text.Lazy.Builder.Int (decimal)
import Data.Text.Internal.Builder.RealFloat.Functions (roundTo)
import Data.Text.Lazy.Builder
import qualified Data.Text as T
#if MIN_VERSION_base(4,11,0)
import Prelude hiding ((<>))
#endif
data FPFormat = Exponent
| Fixed
| Generic
deriving (Int -> FPFormat
FPFormat -> Int
FPFormat -> [FPFormat]
FPFormat -> FPFormat
FPFormat -> FPFormat -> [FPFormat]
FPFormat -> FPFormat -> FPFormat -> [FPFormat]
(FPFormat -> FPFormat)
-> (FPFormat -> FPFormat)
-> (Int -> FPFormat)
-> (FPFormat -> Int)
-> (FPFormat -> [FPFormat])
-> (FPFormat -> FPFormat -> [FPFormat])
-> (FPFormat -> FPFormat -> [FPFormat])
-> (FPFormat -> FPFormat -> FPFormat -> [FPFormat])
-> Enum FPFormat
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: FPFormat -> FPFormat -> FPFormat -> [FPFormat]
$cenumFromThenTo :: FPFormat -> FPFormat -> FPFormat -> [FPFormat]
enumFromTo :: FPFormat -> FPFormat -> [FPFormat]
$cenumFromTo :: FPFormat -> FPFormat -> [FPFormat]
enumFromThen :: FPFormat -> FPFormat -> [FPFormat]
$cenumFromThen :: FPFormat -> FPFormat -> [FPFormat]
enumFrom :: FPFormat -> [FPFormat]
$cenumFrom :: FPFormat -> [FPFormat]
fromEnum :: FPFormat -> Int
$cfromEnum :: FPFormat -> Int
toEnum :: Int -> FPFormat
$ctoEnum :: Int -> FPFormat
pred :: FPFormat -> FPFormat
$cpred :: FPFormat -> FPFormat
succ :: FPFormat -> FPFormat
$csucc :: FPFormat -> FPFormat
Enum, ReadPrec [FPFormat]
ReadPrec FPFormat
Int -> ReadS FPFormat
ReadS [FPFormat]
(Int -> ReadS FPFormat)
-> ReadS [FPFormat]
-> ReadPrec FPFormat
-> ReadPrec [FPFormat]
-> Read FPFormat
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [FPFormat]
$creadListPrec :: ReadPrec [FPFormat]
readPrec :: ReadPrec FPFormat
$creadPrec :: ReadPrec FPFormat
readList :: ReadS [FPFormat]
$creadList :: ReadS [FPFormat]
readsPrec :: Int -> ReadS FPFormat
$creadsPrec :: Int -> ReadS FPFormat
Read, Int -> FPFormat -> ShowS
[FPFormat] -> ShowS
FPFormat -> String
(Int -> FPFormat -> ShowS)
-> (FPFormat -> String) -> ([FPFormat] -> ShowS) -> Show FPFormat
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FPFormat] -> ShowS
$cshowList :: [FPFormat] -> ShowS
show :: FPFormat -> String
$cshow :: FPFormat -> String
showsPrec :: Int -> FPFormat -> ShowS
$cshowsPrec :: Int -> FPFormat -> ShowS
Show)
realFloat :: (RealFloat a) => a -> Builder
{-# SPECIALIZE realFloat :: Float -> Builder #-}
{-# SPECIALIZE realFloat :: Double -> Builder #-}
realFloat :: a -> Builder
realFloat a
x = FPFormat -> Maybe Int -> a -> Builder
forall a. RealFloat a => FPFormat -> Maybe Int -> a -> Builder
formatRealFloat FPFormat
Generic Maybe Int
forall a. Maybe a
Nothing a
x
formatRealFloat :: (RealFloat a) =>
FPFormat
-> Maybe Int
-> a
-> Builder
{-# SPECIALIZE formatRealFloat :: FPFormat -> Maybe Int -> Float -> Builder #-}
{-# SPECIALIZE formatRealFloat :: FPFormat -> Maybe Int -> Double -> Builder #-}
formatRealFloat :: FPFormat -> Maybe Int -> a -> Builder
formatRealFloat FPFormat
fmt Maybe Int
decs a
x
| a -> Bool
forall a. RealFloat a => a -> Bool
isNaN a
x = Builder
"NaN"
| a -> Bool
forall a. RealFloat a => a -> Bool
isInfinite a
x = if a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
0 then Builder
"-Infinity" else Builder
"Infinity"
| a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
0 Bool -> Bool -> Bool
|| a -> Bool
forall a. RealFloat a => a -> Bool
isNegativeZero a
x = Char -> Builder
singleton Char
'-' Builder -> Builder -> Builder
<> FPFormat -> ([Int], Int) -> Builder
doFmt FPFormat
fmt (a -> ([Int], Int)
forall a. RealFloat a => a -> ([Int], Int)
floatToDigits (-a
x))
| Bool
otherwise = FPFormat -> ([Int], Int) -> Builder
doFmt FPFormat
fmt (a -> ([Int], Int)
forall a. RealFloat a => a -> ([Int], Int)
floatToDigits a
x)
where
doFmt :: FPFormat -> ([Int], Int) -> Builder
doFmt FPFormat
format ([Int]
is, Int
e) =
let ds :: String
ds = (Int -> Char) -> [Int] -> String
forall a b. (a -> b) -> [a] -> [b]
map Int -> Char
i2d [Int]
is in
case FPFormat
format of
FPFormat
Generic ->
FPFormat -> ([Int], Int) -> Builder
doFmt (if Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
|| Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
7 then FPFormat
Exponent else FPFormat
Fixed)
([Int]
is,Int
e)
FPFormat
Exponent ->
case Maybe Int
decs of
Maybe Int
Nothing ->
let show_e' :: Builder
show_e' = Int -> Builder
forall a. Integral a => a -> Builder
decimal (Int
eInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) in
case String
ds of
String
"0" -> Builder
"0.0e0"
[Char
d] -> Char -> Builder
singleton Char
d Builder -> Builder -> Builder
<> Builder
".0e" Builder -> Builder -> Builder
<> Builder
show_e'
(Char
d:String
ds') -> Char -> Builder
singleton Char
d Builder -> Builder -> Builder
<> Char -> Builder
singleton Char
'.' Builder -> Builder -> Builder
<> String -> Builder
fromString String
ds' Builder -> Builder -> Builder
<> Char -> Builder
singleton Char
'e' Builder -> Builder -> Builder
<> Builder
show_e'
[] -> String -> Builder
forall a. HasCallStack => String -> a
error String
"formatRealFloat/doFmt/Exponent/Nothing: []"
Just Int
dec ->
let dec' :: Int
dec' = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
dec Int
1 in
case [Int]
is of
[Int
0] -> Builder
"0." Builder -> Builder -> Builder
<> Text -> Builder
fromText (Int -> Text -> Text
T.replicate Int
dec' Text
"0") Builder -> Builder -> Builder
<> Builder
"e0"
[Int]
_ ->
let (Int
ei,[Int]
is') = Int -> [Int] -> (Int, [Int])
roundTo (Int
dec'Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) [Int]
is
is'' :: String
is'' = (Int -> Char) -> [Int] -> String
forall a b. (a -> b) -> [a] -> [b]
map Int -> Char
i2d (if Int
ei Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 then [Int] -> [Int]
forall a. [a] -> [a]
init [Int]
is' else [Int]
is')
in case String
is'' of
[] -> String -> Builder
forall a. HasCallStack => String -> a
error String
"formatRealFloat/doFmt/Exponent/Just: []"
(Char
d:String
ds') -> Char -> Builder
singleton Char
d Builder -> Builder -> Builder
<> Char -> Builder
singleton Char
'.' Builder -> Builder -> Builder
<> String -> Builder
fromString String
ds' Builder -> Builder -> Builder
<> Char -> Builder
singleton Char
'e' Builder -> Builder -> Builder
<> Int -> Builder
forall a. Integral a => a -> Builder
decimal (Int
eInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
ei)
FPFormat
Fixed ->
let
mk0 :: String -> Builder
mk0 String
ls = case String
ls of { String
"" -> Builder
"0" ; String
_ -> String -> Builder
fromString String
ls}
in
case Maybe Int
decs of
Maybe Int
Nothing
| Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 -> Builder
"0." Builder -> Builder -> Builder
<> Text -> Builder
fromText (Int -> Text -> Text
T.replicate (-Int
e) Text
"0") Builder -> Builder -> Builder
<> String -> Builder
fromString String
ds
| Bool
otherwise ->
let
f :: a -> String -> String -> Builder
f a
0 String
s String
rs = String -> Builder
mk0 (ShowS
forall a. [a] -> [a]
reverse String
s) Builder -> Builder -> Builder
<> Char -> Builder
singleton Char
'.' Builder -> Builder -> Builder
<> String -> Builder
mk0 String
rs
f a
n String
s String
"" = a -> String -> String -> Builder
f (a
na -> a -> a
forall a. Num a => a -> a -> a
-a
1) (Char
'0'Char -> ShowS
forall a. a -> [a] -> [a]
:String
s) String
""
f a
n String
s (Char
r:String
rs) = a -> String -> String -> Builder
f (a
na -> a -> a
forall a. Num a => a -> a -> a
-a
1) (Char
rChar -> ShowS
forall a. a -> [a] -> [a]
:String
s) String
rs
in
Int -> String -> String -> Builder
forall a. (Eq a, Num a) => a -> String -> String -> Builder
f Int
e String
"" String
ds
Just Int
dec ->
let dec' :: Int
dec' = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
dec Int
0 in
if Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 then
let
(Int
ei,[Int]
is') = Int -> [Int] -> (Int, [Int])
roundTo (Int
dec' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
e) [Int]
is
(String
ls,String
rs) = Int -> String -> (String, String)
forall a. Int -> [a] -> ([a], [a])
splitAt (Int
eInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
ei) ((Int -> Char) -> [Int] -> String
forall a b. (a -> b) -> [a] -> [b]
map Int -> Char
i2d [Int]
is')
in
String -> Builder
mk0 String
ls Builder -> Builder -> Builder
<> (if String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
rs then Builder
"" else Char -> Builder
singleton Char
'.' Builder -> Builder -> Builder
<> String -> Builder
fromString String
rs)
else
let (Int
ei,[Int]
is') = Int -> [Int] -> (Int, [Int])
roundTo Int
dec' (Int -> Int -> [Int]
forall a. Int -> a -> [a]
replicate (-Int
e) Int
0 [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ [Int]
is)
is'' :: String
is'' = (Int -> Char) -> [Int] -> String
forall a b. (a -> b) -> [a] -> [b]
map Int -> Char
i2d (if Int
ei Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 then [Int]
is' else Int
0Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
:[Int]
is')
in case String
is'' of
[] -> String -> Builder
forall a. HasCallStack => String -> a
error String
"formatRealFloat/doFmt/Fixed: []"
(Char
d:String
ds') -> Char -> Builder
singleton Char
d Builder -> Builder -> Builder
<> (if String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
ds' then Builder
"" else Char -> Builder
singleton Char
'.' Builder -> Builder -> Builder
<> String -> Builder
fromString String
ds')
floatToDigits :: (RealFloat a) => a -> ([Int], Int)
{-# SPECIALIZE floatToDigits :: Float -> ([Int], Int) #-}
{-# SPECIALIZE floatToDigits :: Double -> ([Int], Int) #-}
floatToDigits :: a -> ([Int], Int)
floatToDigits a
0 = ([Int
0], Int
0)
floatToDigits a
x =
let
(Integer
f0, Int
e0) = a -> (Integer, Int)
forall a. RealFloat a => a -> (Integer, Int)
decodeFloat a
x
(Int
minExp0, Int
_) = a -> (Int, Int)
forall a. RealFloat a => a -> (Int, Int)
floatRange a
x
p :: Int
p = a -> Int
forall a. RealFloat a => a -> Int
floatDigits a
x
b :: Integer
b = a -> Integer
forall a. RealFloat a => a -> Integer
floatRadix a
x
minExp :: Int
minExp = Int
minExp0 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
p
(Integer
f, Int
e) =
let n :: Int
n = Int
minExp Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
e0 in
if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 then (Integer
f0 Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`quot` (Integer -> Int -> Integer
expt Integer
b Int
n), Int
e0Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
n) else (Integer
f0, Int
e0)
(Integer
r, Integer
s, Integer
mUp, Integer
mDn) =
if Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 then
let be :: Integer
be = Integer -> Int -> Integer
expt Integer
b Int
e in
if Integer
f Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer -> Int -> Integer
expt Integer
b (Int
pInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) then
(Integer
fInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
beInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
bInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
2, Integer
2Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
b, Integer
beInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
b, Integer
be)
else
(Integer
fInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
beInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
2, Integer
2, Integer
be, Integer
be)
else
if Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
minExp Bool -> Bool -> Bool
&& Integer
f Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer -> Int -> Integer
expt Integer
b (Int
pInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) then
(Integer
fInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
bInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
2, Integer -> Int -> Integer
expt Integer
b (-Int
eInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
2, Integer
b, Integer
1)
else
(Integer
fInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
2, Integer -> Int -> Integer
expt Integer
b (-Int
e)Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
2, Integer
1, Integer
1)
k :: Int
k :: Int
k =
let
k0 :: Int
k0 :: Int
k0 =
if Integer
b Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
2 then
let lx :: Int
lx = Int
p Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
e0
k1 :: Int
k1 = (Int
lx Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
8651) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`quot` Int
28738
in if Int
lx Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 then Int
k1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 else Int
k1
else
Float -> Int
forall a b. (RealFrac a, Integral b) => a -> b
ceiling ((Float -> Float
forall a. Floating a => a -> a
log (Integer -> Float
forall a. Num a => Integer -> a
fromInteger (Integer
fInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
1) :: Float) Float -> Float -> Float
forall a. Num a => a -> a -> a
+
Int -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
e Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float -> Float
forall a. Floating a => a -> a
log (Integer -> Float
forall a. Num a => Integer -> a
fromInteger Integer
b)) Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/
Float -> Float
forall a. Floating a => a -> a
log Float
10)
fixup :: Int -> Int
fixup Int
n =
if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 then
if Integer
r Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
mUp Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<= Integer -> Int -> Integer
expt Integer
10 Int
n Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
s then Int
n else Int -> Int
fixup (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
else
if Integer -> Int -> Integer
expt Integer
10 (-Int
n) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* (Integer
r Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
mUp) Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<= Integer
s then Int
n else Int -> Int
fixup (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
in
Int -> Int
fixup Int
k0
gen :: [t] -> t -> t -> t -> t -> [t]
gen [t]
ds t
rn t
sN t
mUpN t
mDnN =
let
(t
dn, t
rn') = (t
rn t -> t -> t
forall a. Num a => a -> a -> a
* t
10) t -> t -> (t, t)
forall a. Integral a => a -> a -> (a, a)
`quotRem` t
sN
mUpN' :: t
mUpN' = t
mUpN t -> t -> t
forall a. Num a => a -> a -> a
* t
10
mDnN' :: t
mDnN' = t
mDnN t -> t -> t
forall a. Num a => a -> a -> a
* t
10
in
case (t
rn' t -> t -> Bool
forall a. Ord a => a -> a -> Bool
< t
mDnN', t
rn' t -> t -> t
forall a. Num a => a -> a -> a
+ t
mUpN' t -> t -> Bool
forall a. Ord a => a -> a -> Bool
> t
sN) of
(Bool
True, Bool
False) -> t
dn t -> [t] -> [t]
forall a. a -> [a] -> [a]
: [t]
ds
(Bool
False, Bool
True) -> t
dnt -> t -> t
forall a. Num a => a -> a -> a
+t
1 t -> [t] -> [t]
forall a. a -> [a] -> [a]
: [t]
ds
(Bool
True, Bool
True) -> if t
rn' t -> t -> t
forall a. Num a => a -> a -> a
* t
2 t -> t -> Bool
forall a. Ord a => a -> a -> Bool
< t
sN then t
dn t -> [t] -> [t]
forall a. a -> [a] -> [a]
: [t]
ds else t
dnt -> t -> t
forall a. Num a => a -> a -> a
+t
1 t -> [t] -> [t]
forall a. a -> [a] -> [a]
: [t]
ds
(Bool
False, Bool
False) -> [t] -> t -> t -> t -> t -> [t]
gen (t
dnt -> [t] -> [t]
forall a. a -> [a] -> [a]
:[t]
ds) t
rn' t
sN t
mUpN' t
mDnN'
rds :: [Integer]
rds =
if Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 then
[Integer] -> Integer -> Integer -> Integer -> Integer -> [Integer]
forall t. Integral t => [t] -> t -> t -> t -> t -> [t]
gen [] Integer
r (Integer
s Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer -> Int -> Integer
expt Integer
10 Int
k) Integer
mUp Integer
mDn
else
let bk :: Integer
bk = Integer -> Int -> Integer
expt Integer
10 (-Int
k) in
[Integer] -> Integer -> Integer -> Integer -> Integer -> [Integer]
forall t. Integral t => [t] -> t -> t -> t -> t -> [t]
gen [] (Integer
r Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
bk) Integer
s (Integer
mUp Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
bk) (Integer
mDn Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
bk)
in
((Integer -> Int) -> [Integer] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([Integer] -> [Integer]
forall a. [a] -> [a]
reverse [Integer]
rds), Int
k)
minExpt, maxExpt :: Int
minExpt :: Int
minExpt = Int
0
maxExpt :: Int
maxExpt = Int
1100
expt :: Integer -> Int -> Integer
expt :: Integer -> Int -> Integer
expt Integer
base Int
n
| Integer
base Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
2 Bool -> Bool -> Bool
&& Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
minExpt Bool -> Bool -> Bool
&& Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
maxExpt = Array Int Integer
expts Array Int Integer -> Int -> Integer
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> Int -> e
`unsafeAt` Int
n
| Integer
base Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
10 Bool -> Bool -> Bool
&& Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
maxExpt10 = Array Int Integer
expts10 Array Int Integer -> Int -> Integer
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> Int -> e
`unsafeAt` Int
n
| Bool
otherwise = Integer
baseInteger -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^Int
n
expts :: Array Int Integer
expts :: Array Int Integer
expts = (Int, Int) -> [(Int, Integer)] -> Array Int Integer
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
(i, i) -> [(i, e)] -> a i e
array (Int
minExpt,Int
maxExpt) [(Int
n,Integer
2Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^Int
n) | Int
n <- [Int
minExpt .. Int
maxExpt]]
maxExpt10 :: Int
maxExpt10 :: Int
maxExpt10 = Int
324
expts10 :: Array Int Integer
expts10 :: Array Int Integer
expts10 = (Int, Int) -> [(Int, Integer)] -> Array Int Integer
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
(i, i) -> [(i, e)] -> a i e
array (Int
minExpt,Int
maxExpt10) [(Int
n,Integer
10Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^Int
n) | Int
n <- [Int
minExpt .. Int
maxExpt10]]