不用循环,如何判断一个数是2的幂

本文详细解析了如何通过二进制表示来判断一个整数是否为2的幂,通过数学证明展示了当且仅当一个整数与它减一的按位与运算结果为0时,该整数才是2的幂。证明过程涉及二进制位操作和性质,最终揭示了2的幂在二进制表示上的独特特性。

定义:

假设有一个32位无符号非0整数X,它的二进制应该是这个样子的:

B(31) B(30) B(29)...B(0)

假设最高位的1所在的位置为m,最低位的1所在的位置为n,m>= n

X非0,所以n>= 0 && n <= 31我们可以将这个2进制分成三段

SEG1: B(31) - B(m+1)     该段为全0, 长度为31 - (m+1) + 1 = 31 - m,如果m == 31,显然该段就没有

SEG2: B(m) - B(n+1)    该段最高位为1,剩余位任意, 长度为m - n,如果m == n ,显然该段就没有

SEG3: B(n) - B(0)   该最高位为1,其余位为0,  长度为 = n+1


现在回到我们的命题,2的幂有怎样的特征

一个整数乘以2,从位的角度来说就是左移一位,那么2的k次方也就是k个2相乘,左移k-1位:

2E0 = BIT(1)

2E1 = BIT(1 << 1) = BIT(10) = 2

2E2 = BIT(1 << 2) = BIT(100) = 4

2EX = BIT(1 << X) = BIT(1 X个0) 

所以从二进制的角度来看,2的幂一定是一个有且仅有一个1的数


现在回到我们的命题,先给出答案:

A为2的幂,当且仅当(A & (A-1)) == 0


证明:


A表达为BIT(SEG1 SEG2 SEG3),那么A为2的幂,当且仅当A是一个有且仅有一个1的二进制数

由于SEG3有一个1,SEG2长度不为0(m > n)时SEG2一定有至少一个二进制1,所以要求SEG2长度为0,即m==n(也就是SEG1全0,SEG2长度为0, SEG3仅最高位为1)

这样可以得出:

A为2的幂等价于m==n

所以转换目标命题为:

m==n,当且仅当(A & (A-1)) == 0,或者说m==n等价于(A & (A-1)) == 0


A -1的二进制为BIT(SEG1 SEG2 SEG3) - 1

由于SEG3为BIT(1000...000),所以:

A-1 = BIT(SEG1 SEG2 SEG4) 

其中SEG4 = BIT(0 1111...111), 位数为n+1,最高位为0,其余为1

A & (A-1) 

= BIT(SEG1 SEG2 SEG3) & BIT(SEG1 SEG2 SEG4) 

= BIT((SEG1 & SEG1)  (SEG2 & SEG2)  (SEG3 & SEG4))

因为X & X = X,所以:

A & (A-1) = BIT(SEG1 SEG2 SEG3&SEG4)

显然SEG3 & SEG4 = 0,所以:

A & (A-1) = BIT(SEG1 SEG2 SEG5)

其中: SEG5为n+1个0


现在证明:【1】m==n  => (A & (A-1)) == 0

m == n 所以SEG2长度为0,也就不存在,而SEG1和SEG5全0,所以A & (A-1)全0,即证

再证明: 【2】(A & (A-1)) == 0 => m==n

(A & (A-1)) == 0,所以SEG1/SEG2/SEG5全0,对SEG2来说,如果存在那么最高位一定为1,此时m > n,显然与全0冲突,故SEG2不存在,也就是说m<= n

而从定义中可知m>=n,所以m == n,即证


由上可知:

m==n  等价于(A & (A-1)) == 0

证毕

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值