考虑以下等式:
2 ** n = A
我们假设A = 64。
找到n值的最简单方法是什么?
我目前正在使用以下两种方法
A= 64; n = 1; n+=1 while (A >> n) > 0; n-1
A= 64; n = 0; n+=1 until (A == ( 2 ** n));n
有更好的方法吗?
说明同样问题的其他方式:
2 =第n个根A. 如果我知道A的值,我该如何确定n的值?
答案 0 :(得分:9)
试试这个:
def exp_value(n)
Math.log(n) / Math.log(2)
end
答案 1 :(得分:4)
上述答案都不比第一种方法好:
A= 64; n = 1; n+=1 while (A >> n) > 0; n-1
评估Math.log(x)
需要的时间比进行十几个位移要长很多,并且还会给你一个像5.99999999999980235这样的答案来理解。
有关更好的建议,请参阅this SO question。
答案 2 :(得分:3)
log 2 n = ln n / ln 2
因此
log_2_64 = Math.log(64) / Math.log(2)
答案 3 :(得分:0)
建议的答案是好的,但是如果你知道对数有一个上限,即你知道你从不处理大于的数字,你必须计算你的对数并且有一个更有效的方法。 1<<界。
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
如果你没有上限,但你仍然想使用这个算法,你也可以在执行算法之前计算一个界限,但如果性能不是问题,那么我会坚持使用更短的溶液
def bound(n)
bound = 1;
bound >>= 1 while 1 << bound < n
end
答案 4 :(得分:-1)
如果您关心problems mentioned by mobrule。这个怎么样?它与您自己的方法相同,但使用内置函数来明确地传达这个想法。
def exp_value a
(1..a).to_a.detect {|n| 2**n >=a}
end
exp_value 64
=> 6