判断一个数是不是是 4 的整数次幂
Posted
技术标签:
【中文标题】判断一个数是不是是 4 的整数次幂【英文标题】:evaluate whether a number is integer power of 4判断一个数是否是 4 的整数次幂 【发布时间】:2010-08-09 02:00:46 【问题描述】:声称下面的函数是用来判断一个数是否是4的整数次幂。我不太明白它是怎么工作的?
bool fn(unsigned int x)
if ( x == 0 ) return false;
if ( x & (x - 1) ) return false;
return x & 0x55555555;
【问题讨论】:
x & (x - 1) 删除数字的最低 1 位。 【参考方案1】:第一个条件排除了 0,这显然不是 4 的幂,但会错误地通过以下两个测试。 (编辑:不,它不会,正如所指出的那样。第一个测试是多余的。)
下一个是一个不错的技巧:当且仅当数字是 2 的幂时,它才返回 true。2 的幂的特征是只设置一个位。设置了一位的数字减一会导致该数字之前的所有位都被设置(即 0x1000 减一为 0x0111)。和这两个数字,你得到 0。在任何其他情况下(即不是 2 的幂),至少会有一位重叠。
所以在这一点上,我们知道它是 2 的幂。
x & 0x55555555
如果设置了任何偶数位(位 0、位 2、位 4、位 6 等),则返回非零 (=true)。这意味着它是 4 的幂。(即 2 次未通过,但 4 次通过,8 次未通过,16 次通过等)。
【讨论】:
最后一次检查不会使第一次检查变得多余吗?据我所知,0 & 0x55555555
是 0
。
好点。更不用说它真的应该是 0 & 0x55555554(见我的编辑)。
1 怎么会出错?它不是 0,所以它会跳过第一个 if。当与 0 相加时,它是 0,所以它会跳过第二个 if。第三行和-s 设置了 1 位的东西,所以它返回 true。由于 1 = 4^0,它应该返回 true。对吗?【参考方案2】:
每个 4 的幂必须是 1 后跟偶数个零的形式(二进制表示):100...00:
100 = 4
10000 = 16
1000000 = 64
第一个测试(“if”)很明显。
当从 XY100...00 形式的数字中减去 1 时,您会得到 XY011...11。因此,第二个测试检查数字中是否有多个“1”位(本例中为 XY)。
最后一个测试检查这个“1”是否在正确的位置,即位 #2、4、6 等。如果不是,掩码 (&) 将返回非零结果。
【讨论】:
【参考方案3】:以下解决方案适用于 2、4、16 次检查。
public static boolean isPowerOf(int a, int b)
while(b!=0 && (a^b)!=0)
b = b << 1;
return (b!=0)?true:false;
isPowerOf(4,2) > true
isPowerOf(8,2) > true
isPowerOf(8,3) > false
isPowerOf(16,4) > true
【讨论】:
【参考方案4】:var isPowerOfFour = function (n)
let x = Math.log(n) / Math.log(4)
if (Number.isInteger(x))
return true;
else
return false
;
isPowerOfFour(4) ->true
isPowerOfFour(1) ->true
isPowerOfFour(5) ->false
【讨论】:
这不能回答所提出的问题。 具体来说,OP 要求解释如何代码的工作原理,而不是相同功能的替代公式。以上是关于判断一个数是不是是 4 的整数次幂的主要内容,如果未能解决你的问题,请参考以下文章