我找到了一个小算法来确定一个数字是2的幂,但不能解释它是如何工作的,究竟发生了什么?
var potence = n => n && !(n & (n - 1));
for(var i = 2; i <= 16; ++i) {
if(potence(i)) console.log(i + " is potence of 2");
}
答案 0 :(得分:1)
我将解释它对非负n
的作用。 n && !(n & (n - 1))
中的第一个条件只检查n
不为零。如果n
不为零,那么它在某个位置1
处具有一些最不重要的p
位。现在,如果您从1
中减去n
,则位置p
之前的所有位都将更改为1
,p
处的位将翻转为{{1} }}
这样的事情:
0
现在,如果你n: 1010100010100111110010101000000
n-1: 1010100010100111110010100111111
^ position p
这两个位模式,位置&
之后的所有内容都保持不变,之前的所有内容(包括p
)都归零:
p
如果获取after &: 1010100010100111110010100000000
^ position p
后的结果恰好为零,则意味着在&
位置之后没有任何内容,因此该数字必定为
p
,看起来像这样:
2^p
因此n: 0000000000000000000000001000000
n - 1: 0000000000000000000000000111111
n&(n-1): 0000000000000000000000000000000
^ position p
是n
的力量。如果2
的结果不为零(如第一个示例中所示),则表示在&
- 位置之后的更高有效位中存在一些垃圾,因此{{1} }不是p
的力量。
对于负数的2补码表示,我太懒了。
答案 1 :(得分:0)
如果一个数字的电位为2,则二进制表示必须为10 ... 0。减1,然后前导1
应为0
,以便n & (n-1)
为0.否则,它不是2的潜力。
答案 2 :(得分:0)
Kinka的回答基本上是正确的,但也许需要更多关于&#34的详细信息;否则&#34;案件。如果数字不是2的幂,那么它必须具有n =(2 ^ a + 2 ^(b)+ y)的形式,其中a> b且y <2 ^ b。从中减去1必须严格大于2 ^ a,因此(n&amp;(n-1))至少为2 ^ a,因此非零。