{-# LANGUAGE BangPatterns, MagicHash #-} module Data.RangeMin.Common.Math (bit', div', mod', ceilLog, intLog) where -- import Data.Word (Word) import Data.Bits (Bits(..)) import GHC.Exts div' :: Int -> Int -> Int I# i# `div'` I# j# = I# (quotInt# i# j#) mod' :: Int -> Int -> Int I# i# `mod'` I# j# = I# (remInt# i# j#) bit' :: Int -> Int bit' (I# i#) = I# (uncheckedIShiftL# 1# i#) ceilLog :: Int -> Int ceilLog n = intLog (2 * n - 1) intLog :: Int -> Int intLog = wordLog . fromIntegral wordLog :: Word -> Int wordLog v = intLog4 v 0 where intLog4 !v !r | v .&. 0xFFFF0000 == 0 = intLog3 v r | otherwise = intLog3 (v `shiftR` 16) (r .|. 16) intLog3 !v !r | v .&. 0xFF00 == 0 = intLog2 v r | otherwise = intLog2 (v `shiftR` 8) (r .|. 8) intLog2 !v !r | v .&. 0xF0 == 0 = intLog1 v r | otherwise = intLog1 (v `shiftR` 4) (r .|. 4) intLog1 !v !r | v .&. 0xC == 0 = intLog0 v r | otherwise = intLog0 (v `shiftR` 2) (r .|. 2) intLog0 :: Word -> Word -> Int intLog0 !v !r | v .&. 0x2 == 0 = fromIntegral r | otherwise = fromIntegral (r .|. 1)