{-# LANGUAGE NoImplicitPrelude #-}
module Data.NumberLength.Natural
(
lengthNatural
, lengthNaturalHex
)
where
import Prelude
( Bounded(maxBound)
, Integral(quot)
, Num((+))
, (^)
, fromIntegral
)
import Data.Bool (otherwise)
import Data.Eq (Eq((==)))
import Data.Int (Int)
import Data.Ord (Ord((<)))
import Data.Word (Word)
import Numeric.Natural (Natural)
import Data.NumberLength.Internal (either32or64)
import Data.NumberLength.Word (lengthWord, lengthWordHex)
lengthNatural :: Natural -> Int
lengthNatural n
| n < maxWord = lengthWord (fromIntegral n)
| otherwise =
let r = n `quot` (10 ^ maxWordDigits)
in maxWordDigits + if r == 0 then 0 else lengthNatural r
where
maxWordDigits :: Int
maxWordDigits = 10 `either32or64` 20
{-# INLINE lengthNatural #-}
lengthNaturalHex :: Natural -> Int
lengthNaturalHex n
| n < maxWord = lengthWordHex (fromIntegral n)
| otherwise =
let r = n `quot` (16 ^ maxWordDigits)
in maxWordDigits + if r == 0 then 0 else lengthNaturalHex r
where
maxWordDigits :: Int
maxWordDigits = 8 `either32or64` 16
{-# INLINE lengthNaturalHex #-}
maxWord :: Natural
maxWord = fromIntegral (maxBound :: Word)