创建一个方法来查找数字是否为2的幂?

Sha*_*awn 0 ruby methods fixnum

true如果num是2的幂,我有这个代码返回.

def is_power_of_two?(num)
  result = num.inject(0) {|n1, n2| n2 ** n1}
  if result == num
    true
  else
    false
  end
end

p is_power_of_two?(16)
Run Code Online (Sandbox Code Playgroud)

我不断收到错误.我该如何修复和简化此代码?

Car*_*and 7

显然,n是一个非负整数.

def po2?(n)
  n.to_s(2).count('1') == 1
end
Run Code Online (Sandbox Code Playgroud)

例子

po2?  0     #=> false
po2?  1     #=> true
po2? 32     #=> true
po2? 33     #=> false
Run Code Online (Sandbox Code Playgroud)

说明

Fixnum#to_s提供给定基数的整数(接收器)的字符串表示.方法的参数(默认为10)是基础.例如:

16.to_s     #=> "16" 
16.to_s(8)  #=> "20" 
16.to_s(16) #=> "10"
15.to_s(16) #=>  "f"
Run Code Online (Sandbox Code Playgroud)

它是我们感兴趣的基础2.对于2的幂:

 1.to_s(2)  #=>      "1" 
 2.to_s(2)  #=>     "10" 
 4.to_s(2)  #=>    "100" 
 8.to_s(2)  #=>   "1000"
16.to_s(2)  #=>  "10000"
Run Code Online (Sandbox Code Playgroud)

对于一些不是2的幂的自然数:

 3.to_s(2)  #=>    "11" 
 5.to_s(2)  #=>   "101" 
11.to_s(2)  #=>  "1011" 
Run Code Online (Sandbox Code Playgroud)

因此,我们希望匹配包含一个的二进制字符串1.

其他方式

R = /
    \A      # match beginning of string ("anchor")
    10*     # match 1 followed by zero or more zeroes
    \z      # match end of string ("anchor")
    /x      # free-spacing regex definition mode

def po2?(n)
  (n.to_s(2) =~ R) ? true : false
end

po2?(4)  #=> true
po2?(5)  #=> false
Run Code Online (Sandbox Code Playgroud)

还有一条路

这使用Fixnum#bit_lengthFixnum#[]:

def po2?(n)
  m = n.bit_length-1
  n[m] == 1 and m.times.all? { |i| n[i].zero? }
end

po2?  0     #=> false
po2?  1     #=> true
po2? 32     #=> true
po2? 33     #=> false
Run Code Online (Sandbox Code Playgroud)


Mar*_*one 5

尝试:

def is_power_of_two?(num)
  num != 0 && (num & (num - 1)) == 0
end
Run Code Online (Sandbox Code Playgroud)

在这里得到了很好的解释(对于 C#,但 @GregHewgill 的解释也适用于此)