{-# LANGUAGE NoImplicitPrelude #-} -- | -- Module: $HEADER$ -- Description: Get number of digits of a Natural. -- Copyright: (c) 2016, Peter Trško -- License: BSD3 -- -- Stability: experimental -- Portability: NoImplicitPrelude -- -- Get number of digits of a 'Natural'. -- -- /Since 0.2.0.0/ module Data.NumberLength.Natural ( -- * Decimal (base 10) lengthNatural -- * Hexadecimal (base 16) , 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) -- | Number of digits in a @number :: 'Natural'@ in base 10. -- -- /Since 0.2.0.0/ 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 #-} -- | Number of digits in a @number :: 'Natural'@ in base 16. -- -- /Since 0.2.0.0/ 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 #-} -- | Maximum value of type 'Word' cast in to 'Natural'. -- -- /Do not export this function!/ maxWord :: Natural maxWord = fromIntegral (maxBound :: Word)