module GHC.Integer.Logarithms
    ( wordLog2#
    , integerLog2#
    , integerLogBase#
    ) where
#include "MachDeps.h"
#if WORD_SIZE_IN_BITS == 32
# define LD_WORD_SIZE_IN_BITS 5
#elif WORD_SIZE_IN_BITS == 64
# define LD_WORD_SIZE_IN_BITS 6
#else
# error unsupported WORD_SIZE_IN_BITS
#endif
import GHC.Integer.Type
import GHC.Prim
default ()
integerLogBase# :: Integer -> Integer -> Int#
integerLogBase# (S# 2#) m = integerLog2# m
integerLogBase# b m = e'
  where
    (# _, e' #) = go b
    go pw | m `ltInteger` pw = (# m, 0# #)
    go pw = case go (sqrInteger pw) of
              (# q, e #) | q `ltInteger` pw -> (# q, 2# *# e #)
              (# q, e #) -> (# q `quotInteger` pw, 2# *# e +# 1# #)
integerLog2# :: Integer -> Int#
integerLog2# (S# i#) = wordLog2# (int2Word# i#)
integerLog2# (Jn#  _) = 1#
integerLog2# (Jp# bn) = go (s -# 1#)
  where
    s = sizeofBigNat# bn
    go i = case indexBigNat# bn i of
               0## -> go (i -# 1#)
               w   -> wordLog2# w +# (uncheckedIShiftL# i LD_WORD_SIZE_IN_BITS#)
wordLog2# :: Word# -> Int#
wordLog2# w# = (WORD_SIZE_IN_BITS# -# 1#) -# (word2Int# (clz# w#))