number-length-0.1.0.1: src/Data/NumberLength/Word.hs
{-# LANGUAGE NoImplicitPrelude #-}
-- |
-- Module: $HEADER$
-- Description: Get number of digits of a number from a Word-family of numbers
-- in decimal or hexadecimal representation.
-- Copyright: (c) 2015, Peter Trško
-- License: BSD3
--
-- Stability: experimental
-- Portability: NoImplicitPrelude
--
-- Get number of digits of a number from a 'Word'-family of numbers in decimal
-- or hexadecimal representation.
module Data.NumberLength.Word
(
-- * Decimal (base 10)
lengthWord
, lengthWord8
, lengthWord16
, lengthWord32
, lengthWord64
-- * Hexadecimal (base 16)
, lengthWordHex
, lengthWord8hex
, lengthWord16hex
, lengthWord32hex
, lengthWord64hex
)
where
import Prelude
( Integral(quot)
, Num((+))
, fromIntegral
)
import Data.Bool (otherwise)
import Data.Int (Int)
import Data.Ord (Ord((<), (>=)))
import Data.Word (Word, Word16, Word32, Word64, Word8)
import Data.NumberLength.Internal (either32or64)
-- {{{ Decimal ----------------------------------------------------------------
-- | Number of digits in a @number :: 'Word8'@ in base 10.
lengthWord8 :: Word8 -> Int
lengthWord8 n -- Maximum is 255.
| n < 10 = 1
| n < 100 = 2
| otherwise = 3
{-# INLINE lengthWord8 #-}
-- | Number of digits in a @number :: 'Word16'@ in base 10.
lengthWord16 :: Word16 -> Int
lengthWord16 n -- Maximum is 65535.
| n < 10 = 1
| n < 100 = 2
| n < 1000 = 3
| n < 10000 = 4
| otherwise = 5
{-# INLINE lengthWord16 #-}
-- | Number of digits in a @number :: 'Word32'@ in base 10.
lengthWord32 :: Word32 -> Int
lengthWord32 n -- Maximum is 4294967295.
| n < 10 = 1
| n < 100 = 2
| n < 1000 = 3
| n < 10000 = 4
| n >= 100000000 = 8 + lengthWord32 (n `quot` 100000000)
| otherwise = 4 + lengthWord32 (n `quot` 10000)
-- n >= 10000
{-# INLINE lengthWord32 #-}
-- | Number of digits in a @number :: 'Word64'@ in base 10.
lengthWord64 :: Word64 -> Int
lengthWord64 n -- Maximum is 18446744073709551615.
| n < 10 = 1
| n < 100 = 2
| n < 1000 = 3
| n < 10000 = 4
| n >= 10000000000000000 = 16 + lengthWord64 (n `quot` 10000000000000000)
| n >= 100000000 = 8 + lengthWord64 (n `quot` 100000000)
| otherwise = 4 + lengthWord64 (n `quot` 10000)
-- n >= 10000
{-# INLINE lengthWord64 #-}
-- | Number of digits in a @number :: 'Word'@ in base 10.
lengthWord :: Word -> Int
lengthWord n =
lengthWord32 (fromIntegral n) `either32or64` lengthWord64 (fromIntegral n)
{-# INLINE lengthWord #-}
-- }}} Decimal ----------------------------------------------------------------
-- {{{ Hexadecimal ------------------------------------------------------------
-- | Number of digits in a @number :: 'Word8'@ in base 16.
lengthWord8hex :: Word8 -> Int
lengthWord8hex n -- Maximum is 255 = 0xff.
| n < 16 = 1
| otherwise = 2
{-# INLINE lengthWord8hex #-}
-- | Number of digits in a @number :: 'Word16'@ in base 16.
lengthWord16hex :: Word16 -> Int
lengthWord16hex n -- Maximum is 65535 = 0xffff.
| n < 0x10 = 1
| n < 0x100 = 2
| n < 0x1000 = 3
| otherwise = 4
{-# INLINE lengthWord16hex #-}
-- | Number of digits in a @number :: 'Word32'@ in base 16.
lengthWord32hex :: Word32 -> Int
lengthWord32hex n -- Maximum is 4294967295 = 0xffffffff.
| n < 0x10 = 1
| n < 0x100 = 2
| n < 0x1000 = 3
| n < 0x10000 = 4
| otherwise = 4 + lengthWord32hex (n `quot` 0x10000)
-- n >= 0x10000
{-# INLINE lengthWord32hex #-}
-- | Number of digits in a @number :: 'Word64'@ in base 16.
lengthWord64hex :: Word64 -> Int
lengthWord64hex n -- Maximum is 18446744073709551615 = 0xffffffffffffffff.
| n < 0x10 = 1
| n < 0x100 = 2
| n < 0x1000 = 3
| n < 0x10000 = 4
| n >= 0x100000000 = 8 + lengthWord64hex (n `quot` 0x100000000)
| otherwise = 4 + lengthWord64hex (n `quot` 0x10000)
-- n >= 0x10000
{-# INLINE lengthWord64hex #-}
-- | Number of digits in a @number :: 'Word'@ in base 16.
lengthWordHex :: Word -> Int
lengthWordHex n = lengthWord32hex (fromIntegral n)
`either32or64` lengthWord64hex (fromIntegral n)
{-# INLINE lengthWordHex #-}
-- }}} Hexadecimal ------------------------------------------------------------