【问题标题】:What is the most programatically efficient way to determine if a number is a power of 2?确定数字是否为 2 的幂的最有效的编程方法是什么?
【发布时间】:2013-09-12 11:05:08
【问题描述】:

只是一个简单的布尔真/假是非常有效的会很好。我应该使用递归,还是有更好的方法来确定它?

【问题讨论】:

  • 查看它的二进制表示。模除法和整数除法的组合可能会起作用。
  • 这里的一些C方案可能适用:stackoverflow.com/questions/600293/…
  • 我试图记住——类似于与 1 + 1 的补码的与。无论如何,我很确定它可以在 4-5 个简单的操作中完成。
  • @Thilo - 你只是链接回这个问题。
  • @Skylion,您应该将已接受的答案移回 Mitch(让他将我的插图复制进去);我只是说明他的答案

标签: java performance math recursion binary


【解决方案1】:

来自here

判断一个整数是否是2的幂

unsigned int v; // we want to see if v is a power of 2
bool f;         // the result goes here 

f = (v & (v - 1)) == 0;

请注意,此处将 0 错误地视为 2 的幂。补救 这个,使用:

f = v && !(v & (v - 1));

为什么会这样? 2 的整数幂只有一个位集。减 1 的效果是将该位更改为 0,并将其下方的所有位更改为 1。 AND'ing 使用原始数字将始终导致全零。

【讨论】:

  • @MitchWheat 底部的不是惯用的。编译器会抛出一个错误,因为它会假设您要将int 分配给f。它应该看起来像这样f = v != 0 && (v & (v - 1)) == 0;
【解决方案2】:

2 的整数幂将是 1 后跟一个或多个零

     Value          value -1 (binary)
   10      2              1
   100     4             11 
   1000    8            111 
   10000  16           1111 

正如mitch所说

  (value & (value-1)) == 0

value 是 2 的幂(但不是除 1 / 0 之外的任何其他数字,并且 1 通常被视为 2 的 0 次幂)。

对于米奇的解决方案,其中数字 > 0 不是 2 的幂,即

    value              value - 1       V & (v-1)
   1000001             1000000         1000000
   1000010             1000001         1000000
   1000100             1000011         1000000
   1001000             1000111         1000000

   1000011             1000010         1000010
   1000101             1000100         1000100
   1000111             1000110         1000110

而且永远不会为零。

从数字中减去 1 会将位反转,直到并包括第一个 1;对于二的幂,只有一个“1”,因此 Value & (Value-1) == 0,对于其他数字,第二个和后续的 1 不受影响。

需要排除零


另一种可能的解决方案(可能稍微慢一些)是

   A & (-A) == A


Powers of 2:
     A      -A 
   00001 & 11111 = 00001
   00010 & 11110 = 00010
   00100 & 11100 = 00100

其他一些数字:

     A      -A 
   00011 & 11101 = 00001
   00101 & 11011 = 00001

同样,您还需要排除 0


为了解决这个问题,我做到了

  1. 以二进制写入数字;你会看到 2 的幂只有一个。
  2. 在布尔级别使用各种运算符/布尔值,看看有什么用

这样做,我发现以下方法也有效:

  A & (-A) == A        
 (not A) | (not A + 1) == -1    /* boolean not of a & (a-1) == 0 */

【讨论】:

  • 不需要循环
  • 是的,这里的原始版本远非最佳答案。
【解决方案3】:

不确定您是指计算速度方面的效率,还是代码行方面的效率。但你可以试试value == Integer.highestOneBit(value)。如果需要,不要忘记排除零。

【讨论】:

  • 我的意思是计算速度。
  • 恐怕,highestOneBit 是为数不多的慢操作之一,见this list。但是您可以使用lowestOneBit,它的速度要快得多(因为它使用了已接受答案中的技巧)。
  • 哈哈,我下次抛硬币小心点!
猜你喜欢
  • 1970-01-01
  • 2011-07-19
  • 2010-10-23
  • 1970-01-01
  • 1970-01-01
  • 2010-09-11
  • 1970-01-01
  • 2011-03-08
  • 1970-01-01
相关资源
最近更新 更多