haquil-0.2.1.5: src/Data/Int/Util.hs
-----------------------------------------------------------------------------
--
-- Module : $Header$
-- Copyright : (c) 2017-18 Brian W Bush
-- License : MIT
--
-- Maintainer : Brian W Bush <code@functionally.io>
-- Stability : Stable
-- Portability : Portable
--
-- | Integer functions.
--
-----------------------------------------------------------------------------
{-# LANGUAGE Safe #-}
module Data.Int.Util (
-- * Functions
ilog2
, isqrt
, ilog2sqrt
) where
import Control.Arrow ((&&&))
-- | Square root of an integer.
--
-- This is equivalent to:
--
-- @
-- isqrt x == floor (sqrt $ from Integral x)
-- @
isqrt :: (Enum a, Num a, Ord a)
=> a -- ^ The integer.
-> a -- ^ The integral square root.
isqrt n
| n < fst (head table) = error "isqrt: illegal argument."
| otherwise = snd . head $ dropWhile ((< n) . fst) table
where
table = tabulate (^ (2 :: Int))
-- | Base-two logarithm of an integer.
--
-- This is equivalent to:
--
-- @
-- ilog2 x == floor (logBase 2 $ fromIntegral x)
-- @
ilog2 :: (Enum a, Integral a, Ord a)
=> a -- ^ The integer.
-> a -- ^ The integral base-two logarithm.
ilog2 n
| n < fst (head table) = error "ilog2: illegal argument."
| otherwise = snd . head $ dropWhile ((< n) . fst) table
where
table = tabulate (2^)
-- | Base-two logarithm of the square root of an integer.
--
-- This is equivalent to:
--
-- @
-- ilog2sqrt x == floor (logBase 2 . sqrt $ fromIntegral x)
-- @
ilog2sqrt :: (Enum a, Integral a, Num a, Ord a)
=> a -- ^ The integer.
-> a -- ^ The integral base-two logarithm of the square root.
ilog2sqrt n
| n < fst (head table) = error "ilog2sqrt: illegal argument."
| otherwise = snd . head $ dropWhile ((< n) . fst) table
where
table = tabulate (^ (2 :: Int))
-- | Tabulate a function for later use.
tabulate :: (Enum a, Num a)
=> (a -> a) -- ^ The function.
-> [(a, a)] -- ^ Its tabulation.
tabulate f = (f &&& id) <$> [0..]