如何在Ruby中找到exponent的值?

时间:2009-10-14 00:31:24

标签: ruby-on-rails ruby jruby

考虑以下等式:

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的值?

5 个答案:

答案 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