Reputation: 64363
Consider the equation below:
2 ** n = A
Let us assume A=64.
What is the easiest way to find the value of n?
I am currently using following two approaches
A= 64; n = 1; n+=1 while (A >> n) > 0; n-1
A= 64; n = 0; n+=1 until (A == ( 2 ** n));n
Is there a better approach?
Other way of stating the same problem:
2 = nth root A If I know the value of A, how do I determine the value of n?
Upvotes: 1
Views: 3324
Reputation: 1029
The proposed answer is good, but you have to count up to your logarithm and there is a slightly more efficient way, if you know that the logarithm has an upper bound, i.e. if you know that you never deal with numbers larger than 1 << bound.
def faster_log2(n)
l = 0; bound = 64
while bound > 0
if 1 << bound > n
n >>= bound; l += bound
end
bound >>= 1
end
l
end
If you don't have an upper bound, but you still want to use this algorithm, you can also calculate a bound before executing the algorithm, but if performance is not an issue, then I would stick with the shorter solution.
def bound(n)
bound = 1;
bound >>= 1 while 1 << bound < n
end
Upvotes: 0
Reputation: 40751
If you care about the problems mentioned by mobrule. How about this? It is the same as your own method but use built-in function to communicate the idea explictly.
def exp_value a
(1..a).to_a.detect {|n| 2**n >=a}
end
exp_value 64
=> 6
Upvotes: -1
Reputation: 118635
Neither of the above answers is better than your first approach:
A= 64; n = 1; n+=1 while (A >> n) > 0; n-1
Evaluating Math.log(x)
takes a lot longer than doing a dozen bit-shifts, and will also give you an answer like 5.99999999999980235 to make sense of.
See this SO question for some better ideas.
Upvotes: 5
Reputation: 53940
log2n = ln n / ln 2
hence
log_2_64 = Math.log(64) / Math.log(2)
Upvotes: 3