检查所有位是否为 1 的最佳方法是什么?
What is the best way to check if all bits are 1?
由于 ~,我认为这很容易,但是 ~ 只是 returns 负值 2^x 而不是 0。
最简单的方法是检查 0
是否出现在 bin(n)
中。以下是一些示例:
全 1 的数字:
>>> n=15
>>> bin(n)
'0b1111'
>>> bin(n)[2:]
'1111'
>>> '0' in bin(n)[2:]
False
有 1 个或多个 0 的数字:
>>> n=5
>>> bin(n)
'0b101'
>>> bin(n)[2:]
'101'
>>> '0' in bin(n)[2:]
True
您可以修改标准 bithack 来检查数字是否为 2 的幂(小于 2 的幂的数字均为 1),特殊情况检查为零:
def allOnes(n):
return ((n+1) & n == 0) and (n!=0)
print allOnes(255)
print allOnes(158)
print allOnes(0)
print allOnes(-1)
print allOnes(-2)
输出:
True
False
False
True
False
大多数语言使用 MSB(最高有效位)作为有符号值位。例如,二进制的 00000001 是十进制的 1,二进制的 10000011 是十进制的 -125(因为 MSB 是 1 (-128) & 00000011 是十进制的 3 (-128 + 3 = -125))。
因此所有位都是1的二进制数在十进制中相当于-1。
所以简单地说,如果 byte_value 是一个带符号的整数,
if(byte_value = -1)
{
printf("All One's");
}
else
{
printf("All Not One's");
}
否则
if(byte_value = 255)
{
printf("All One's");
}
else
{
printf("All Not One's");
}
您可能需要的是 XOR (^
) 运算符,而不是您尝试过的按位非 (~
) 运算符(因为它只会还原每一位)。由于您提到 ~
运算符作为您的初始方法,我假设您想通过与全 1 的整数进行比较来确定整数中的所有位是否为 1。也许您正在优化速度。
异或运算符 return 仅当操作数中的任一位为 1 时才为 1。因此,只要任何位为 0,它都会给出 1。
>>> 100 ^ 000
100
>>> 100 ^ 100
0
>>> 111 ^ 101
10
>>> 111 ^ 111
0
(如您所见,结果整数未被填充,但这对我们的目的无关紧要。)
唯一'gotcha'就是你需要提前知道你的号码的位数
然后您可以通过查看结果数字是否大于 0 来检查其中的所有位是否都是 1。如果是,那么您就知道并非所有位都是 1。
示例:
只要 someNumberWithThreeBits 中的所有位都为 1,someNumberWithThreeBits ^ 111 == 0
将 return 为真,否则为假。
PS:请注意 000 ^ 000 也会 return 0。但是在这种情况下您不会遇到这种情况,除非您决定与 000 而不是 111 进行比较。
基于@samgak 对@Martjin Pieters 关于特定整数大小的评论的回应,如果要求特定大小的所有位都是 1,那么我们的测试需要修改。想象一下,例如,我们要测试一个 nibble 大小的整数在二进制表示中是否全为 1:
In [2]: def all_ones_nibble(to_test: int) -> bool:
...: assert 0 <= to_test < (1 << 4)
...: # bin(1 << 4) == "0b10000", therefore bin((1 << 4) - 1) == "0b1111"
...: return to_test == (1 << 4) - 1
...:
In [3]: all_ones_nibble(int("0", base=2))
Out[3]: False
In [4]: all_ones_nibble(int("1", base=2))
Out[4]: False
In [5]: all_ones_nibble(int("1111", base=2))
Out[5]: True
当然,将自己限制在半字节有点愚蠢,所以让我们概括为任意大小:
In [6]: def all_ones_for_size(to_test: int, size: int) -> bool:
...: return to_test == (1 << size) - 1
...:
In [7]: all_ones_for_size(int("1111", base=2), 4)
Out[7]: True
In [8]: all_ones_for_size(int("11111111", base=2), 8)
Out[8]: True
In [9]: all_ones_for_size(int("11111110", base=2), 8)
Out[9]: False
最后,为了好玩,让我们使用@riteshtch 的技术来获得相同的结果:
In [10]: def all_ones_for_size_using_strs(to_test: int, size: int) -> bool:
...: # NOTE: using a format string obviates the need to shave off "0b".
...: # For example, f"{int('1111', base=2):b}" == "1111", whereas
...: # bin(int("1111", base=2)) == "0b1111"
...: as_bin_str = f"{to_test:b}"
...: return len(as_bin_str) == size and not "0" in as_bin_str
...:
In [11]: all_ones_for_size_using_strs(int("11111110", base=2), 8)
Out[11]: False
In [12]: all_ones_for_size_using_strs(int("11111111", base=2), 8)
Out[12]: True
In [13]: all_ones_for_size_using_strs(int("1111", base=2), 8)
Out[13]: False
请注意,此答案使用 python 3 和 type annotations,这不适用于 python 2.7,但因为 python 2 已经 long-since日落,充满希望的未来观众会发现现代代码更有用。
由于 ~,我认为这很容易,但是 ~ 只是 returns 负值 2^x 而不是 0。
最简单的方法是检查 0
是否出现在 bin(n)
中。以下是一些示例:
全 1 的数字:
>>> n=15
>>> bin(n)
'0b1111'
>>> bin(n)[2:]
'1111'
>>> '0' in bin(n)[2:]
False
有 1 个或多个 0 的数字:
>>> n=5
>>> bin(n)
'0b101'
>>> bin(n)[2:]
'101'
>>> '0' in bin(n)[2:]
True
您可以修改标准 bithack 来检查数字是否为 2 的幂(小于 2 的幂的数字均为 1),特殊情况检查为零:
def allOnes(n):
return ((n+1) & n == 0) and (n!=0)
print allOnes(255)
print allOnes(158)
print allOnes(0)
print allOnes(-1)
print allOnes(-2)
输出:
True
False
False
True
False
大多数语言使用 MSB(最高有效位)作为有符号值位。例如,二进制的 00000001 是十进制的 1,二进制的 10000011 是十进制的 -125(因为 MSB 是 1 (-128) & 00000011 是十进制的 3 (-128 + 3 = -125))。
因此所有位都是1的二进制数在十进制中相当于-1。 所以简单地说,如果 byte_value 是一个带符号的整数,
if(byte_value = -1)
{
printf("All One's");
}
else
{
printf("All Not One's");
}
否则
if(byte_value = 255)
{
printf("All One's");
}
else
{
printf("All Not One's");
}
您可能需要的是 XOR (^
) 运算符,而不是您尝试过的按位非 (~
) 运算符(因为它只会还原每一位)。由于您提到 ~
运算符作为您的初始方法,我假设您想通过与全 1 的整数进行比较来确定整数中的所有位是否为 1。也许您正在优化速度。
异或运算符 return 仅当操作数中的任一位为 1 时才为 1。因此,只要任何位为 0,它都会给出 1。
>>> 100 ^ 000
100
>>> 100 ^ 100
0
>>> 111 ^ 101
10
>>> 111 ^ 111
0
(如您所见,结果整数未被填充,但这对我们的目的无关紧要。)
唯一'gotcha'就是你需要提前知道你的号码的位数
然后您可以通过查看结果数字是否大于 0 来检查其中的所有位是否都是 1。如果是,那么您就知道并非所有位都是 1。
示例:
只要 someNumberWithThreeBits 中的所有位都为 1,someNumberWithThreeBits ^ 111 == 0
将 return 为真,否则为假。
PS:请注意 000 ^ 000 也会 return 0。但是在这种情况下您不会遇到这种情况,除非您决定与 000 而不是 111 进行比较。
基于@samgak 对@Martjin Pieters 关于特定整数大小的评论的回应,如果要求特定大小的所有位都是 1,那么我们的测试需要修改。想象一下,例如,我们要测试一个 nibble 大小的整数在二进制表示中是否全为 1:
In [2]: def all_ones_nibble(to_test: int) -> bool:
...: assert 0 <= to_test < (1 << 4)
...: # bin(1 << 4) == "0b10000", therefore bin((1 << 4) - 1) == "0b1111"
...: return to_test == (1 << 4) - 1
...:
In [3]: all_ones_nibble(int("0", base=2))
Out[3]: False
In [4]: all_ones_nibble(int("1", base=2))
Out[4]: False
In [5]: all_ones_nibble(int("1111", base=2))
Out[5]: True
当然,将自己限制在半字节有点愚蠢,所以让我们概括为任意大小:
In [6]: def all_ones_for_size(to_test: int, size: int) -> bool:
...: return to_test == (1 << size) - 1
...:
In [7]: all_ones_for_size(int("1111", base=2), 4)
Out[7]: True
In [8]: all_ones_for_size(int("11111111", base=2), 8)
Out[8]: True
In [9]: all_ones_for_size(int("11111110", base=2), 8)
Out[9]: False
最后,为了好玩,让我们使用@riteshtch 的技术来获得相同的结果:
In [10]: def all_ones_for_size_using_strs(to_test: int, size: int) -> bool:
...: # NOTE: using a format string obviates the need to shave off "0b".
...: # For example, f"{int('1111', base=2):b}" == "1111", whereas
...: # bin(int("1111", base=2)) == "0b1111"
...: as_bin_str = f"{to_test:b}"
...: return len(as_bin_str) == size and not "0" in as_bin_str
...:
In [11]: all_ones_for_size_using_strs(int("11111110", base=2), 8)
Out[11]: False
In [12]: all_ones_for_size_using_strs(int("11111111", base=2), 8)
Out[12]: True
In [13]: all_ones_for_size_using_strs(int("1111", base=2), 8)
Out[13]: False
请注意,此答案使用 python 3 和 type annotations,这不适用于 python 2.7,但因为 python 2 已经 long-since日落,充满希望的未来观众会发现现代代码更有用。