我正在寻找一种创新的方法来检查一个数字在一个有符号的int中是否只有一个位。
我很清楚我可以简单地使用计数器,一些模块化分区和一个位移来进行循环。但我很好奇是否有更好的方法,因为我们只想找到一个位。
bool HasOnlyOneBit (int numb)
{
//return true if numb has only one bit (I.E. is equal to 1, 2, 4, 8, 16... Int.MinValue)
}
答案 0 :(得分:43)
return x == (x & -x);
这个答案是有效的,因为设计了两个补码表示法。
首先,一个例子。假设我们有8位有符号整数。
00010000 = 16
11110000 = -16
按位,结果会给你00010000
,等于原始值!这样做的原因是因为在2的补码中否定时,首先反转所有的位,然后加1.你将有一堆零和一堆进位,直到一个位置到位。按位然后检查我们是否设置了正确的位。
如果数字不是2的幂:
00101010 = 42
& 11010110 = -42
----------
00000010 != 42
您的结果仍然只有一位,但它与原始值不匹配。因此,您的原始值设置了多个位。
注意:此技术对0返回true,这可能是也可能不是。
答案 1 :(得分:25)
这是一个着名的问题
(x & x-1) == 0
来自Wiki的2的力量:here
64 = 01000000 (x)
63 = 00111111 (x-1)
______________
& = 00000000 == 0
______________
其他位为ON时的情况
18 = 00010010 (x)
17 = 00010001 (x-1)
______________
& = 00010000 != 0
______________
答案 2 :(得分:8)
我建议您查看Bit Twiddling Hacks页面,然后在“Determining if an integer is a power of 2”或“Counting bits set”下选择最合适的选项。
答案 3 :(得分:2)
return (x && ((x & x-1) == 0))
答案 4 :(得分:1)
return (x && (0x8000000000000000ULL % x));
这是以下代码的简化:
if (x == 0) {
return false;
} else if (0x8000000000000000ULL % x) {
return false;
} else {
return true;
}
说明:0x8000000000000000是最高的"仅1比特" 64位寄存器的值。只有一个除以另一个" 1位"值将导致无余数。
答案 5 :(得分:0)
将日志记录到您的号码的第2位,如果它是一个整数,则您的号码只有1位。不确定我认为这比任何被排除的选项更好。
答案 6 :(得分:0)
Python3内存高效解决方案
return n > 0 and (n & (n-1)) == 0