这个问题在这里已经有了答案:
How do you set, clear, and toggle a single bit?
(27 个回答)
6年前关闭。
我们有一个整数
int x = 50;
在二进制中,它是
00110010
如何以编程方式更改第四(第 4)位?
最佳答案
您可以通过将数字与除第四位以外的任何地方都为零的值进行“或”运算来设置数字的第四位。这可以做为
x |= (1u << 3);
类似地,您可以通过与除第四位以外的任何地方都为 1 的值进行 AND 运算来清除第四位。例如:
x &= ~(1u << 3);
最后,您可以通过将第四位与除第四位以外的任何地方都为零的值进行异或来切换第四位:
x ^= (1u << 3);
要了解为什么会这样,我们需要看两件事:
<<
的行为是什么?运营商在这种情况下? 在上述所有三个代码片段中,我们都使用了
<<
运算符来生成一个值。 <<
运算符是按位左移运算符,它接受一个值,然后将其所有位向左移动一定数量的步数。在你的情况下,我用1u << 3
取值 1(二进制表示为 1),然后将其所有位移位三个点,用 0 填充缺失值。这将创建二进制值
1000
,在第四位设置了一个位。现在,为什么
x |= (1u << 3);
设置数字的第四位?这与 OR 运算符的工作方式有关。
|=
运算符就像 +=
或 *=
除了按位或 - 它相当于x = x | (1u << 3);
那么为什么 x 与二进制值
1000
进行 OR 运算?设置它的第四位?这与 OR 的定义方式有关:0 | 0 == 0
0 | 1 == 1
1 | 0 == 1
1 | 1 == 1
更重要的是,我们可以更紧凑地将其重写为
x | 0 == x
x | 1 == 1
这是一个极其重要的事实,因为这意味着对任何位与零进行 OR 运算不会改变该位的值,而对任何位与 1 进行 OR 运算总是将该位设置为 1。这意味着当我们写
x |= (1u << 3);
由于 (1u << 3) 是一个值,除了第四位之外,其他任何地方都为零,因此按位 OR 使 x 的所有位保持不变,除了第四位,然后将其设置为 1。更一般地,将一个数字与一系列零和一的值进行 OR 运算将保留所有位为零的值,并设置所有位为 1 的值。
现在,让我们看看
x &= ~(1u << 3);
这使用按位补码运算符
~
,它接受一个数字并翻转它的所有位。如果我们假设整数是两个字节(只是为了简单起见),这意味着 (1u << 3)
的实际编码是0000000000001000
当我们取这个的补码时,我们得到数字
1111111111110111
现在,让我们看看当我们将两个值按位 AND 在一起时会发生什么。 AND 运算符有一个有趣的真值表:
0 & 0 == 0
0 & 1 == 0
1 & 0 == 0
1 & 1 == 1
或者,更简洁:
x & 0 == 0
x & 1 == x
请注意,这意味着如果我们将两个数字 AND 在一起,结果值将是所有与零进行 AND 运算的位都设置为零,而所有其他位都保留。这意味着如果我们与
~(1u << 3)
我们正在与
1111111111110111
因此,根据我们的上表,这意味着“保留除第四位之外的所有位,原样,然后将第四位更改为零。”
更一般地,如果您想清除一组位,请创建一个数字,该数字在您想要保持位不变的任何地方都是一个,而在您想要清除这些位的地方则是零。
最后,让我们看看为什么
x ^= (1u << 3)
翻转数字的第四位。这是因为二元异或运算符有这个真值表:
0 ^ 0 == 0
0 ^ 1 == 1
1 ^ 0 == 1
1 ^ 1 == 0
请注意
x ^ 0 == 0
x ^ 1 == ~x
哪里
~x
是 x 的反义词; 1 为 0,0 为 1。这意味着如果我们对 x 与值 (1u << 3)
进行异或,我们将它与0000000000001000
所以这意味着“保持除第四位以外的所有位保持原样,但翻转第四位。”更一般地,如果您想翻转一些位,请将值与一个数字进行异或,该数字在您希望保持位完整的位置为零,在您希望翻转这些位的位置为一个。
希望这可以帮助!
关于c++ - 改变一点整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6916974/