そして、右側でそれを使用して、どうすればソリューションをより低い数値にまでさかのぼることができますか?
再帰。フロアの計算が簡単なので、次の事実を使用します。
ceiling (log_2 n) == floor (log_2 (2*n-1))
簡単にわかるように。次に、底辺の対数を見つけるために、底辺bの対数を計算してb²調整します。
log2 :: Int -> Int
log2 1 = 0
log2 2 = 1
log2 n
| n < 1 = error "Argument of logarithm must be positive"
| otherwise = fst $ doLog 2 1
where
m = 2*n-1
doLog base acc
| base*acc > m = (0, acc)
| otherwise = case doLog (base*base) acc of
(e, a) | base*a > m -> (2*e, a)
| otherwise -> (2*e+1,a*base)
より多くのステップを必要とするより単純なアルゴリズムは、引数の値に達するか超えるまで、単純に反復し、各ステップで2を乗算し、カウントすることです。
log2 :: Int -> Int
log2 n
| n < 1 = error "agument of logarithm must be positive"
| otherwise = go 0 1
where
go exponent prod
| prod < n = go (exponent + 1) (2*prod)
| otherwise = exponent