改变一个整数
我们有一个整数
int x = 50;
在二进制中,它是
00110010
如何以编程方式更改第四(第4)位?
除了第四位之外,您可以通过将其与除零之外的零值进行或运算来设置数字的第四位。 这可以做到
x |= (1u << 3);
类似地,您可以通过使用除了第四位之外的任何位置的值进行AND运算来清除第四位。 例如:
x &= ~(1u << 3);
最后,你可以通过对第四位进行异或来切换,除了第四位之外,其值为零:
x ^= (1u << 3);
要了解其工作原理,我们需要考虑两件事:
- 在这种情况下
<<
运算符的行为是什么? - 这里的AND,OR和XOR运算符的行为是什么?
在上述所有三个代码片段中,我们使用<<
运算符生成一个值。 <<
运算符是按位左移运算符,它接受一个值,然后将其所有位向左移动一些步骤。 在你的情况下,我用过
1u << 3
取值1(具有二进制表示1)然后将其所有位移到三个点上,用0填充缺失值。这将创建二进制值1000
,其在第四位中设置了位。
现在,为什么呢
x |= (1u << 3);
设置数字的第四位? 这与OR运算符的工作方式有关。 |=
运算符类似于+=
或*=
除了按位OR - 它相当于
x = x | (1u << 3);
那么为什么OR与x的二进制值1000
设置其第四位? 这与定义OR的方式有关:
0 | 0 == 0 0 | 1 == 1 1 | 0 == 1 1 | 1 == 1
更重要的是,我们可以更紧凑地重写它
x | 0 == x x | 1 == 1
这是一个非常重要的事实,因为它意味着对任何位进行OR运算不会改变位的值,而对任何位进行OR运算总是将该位设置为1。 这意味着我们写作时
x |= (1u << 3);
因为除了第四位之外,(1u << 3)是除了第四位之外的所有零都是零的值,所以按位OR使x的所有位保持不变,除了第四位,然后将其设置为1。 更一般地,对具有一系列零和1的值进行OR运算将保留位为零的所有值,并设置位为1的所有值。
现在,让我们来看看
x &= ~(1u << 3);
这使用了按位补码运算符~
,它取一个数字并翻转其所有位。 如果我们假设整数是两个字节(只是为了简单),这意味着(1u << 3)
的实际编码是
0000000000001000
当我们采用这个补充时,我们得到数字
1111111111110111
现在,让我们看看当我们将两个值一起按位时会发生什么。 AND运算符有这个有趣的真值表:
0 & 0 == 0 0 & 1 == 0 1 & 0 == 0 1 & 1 == 1
或者,更紧凑:
x & 0 == 0 x & 1 == x
请注意,这意味着如果我们将两个数字和两个数字放在一起,结果值将使所有位为0的AND-ed都设置为零,而所有其他位都保留。 这意味着,如果我们和
~(1u << 3)
我们正在和他们打交道
1111111111110111
因此,通过上面的表格,这意味着“保留所有位,除了第四位,原样,然后将第四位更改为零。”
更一般地说,如果要清除一组位,请创建一个数字,该数字是您希望保持位不变的任何位置,并且在您要清除位的位置为零。
最后,让我们看看为什么
x ^= (1u << 3)
翻转数字的第四位。 这是因为二进制XOR运算符具有此真值表:
0 ^ 0 == 0 0 ^ 1 == 1 1 ^ 0 == 1 1 ^ 1 == 0
请注意
x ^ 0 == 0 x ^ 1 == ~x
其中~x
与x相反; 它为0表示1,1表示0表示如果我们将XOR x与值(1u << 3)
异或运算,我们将它与XOR进行异或运算
0000000000001000
所以这意味着“保留所有位,但第四位按原样设置,但翻转第四位。” 更一般地说,如果你想翻转一些位,那么将值与一个数字进行异或,使得你想要保持位完整的数字为零,并且你想要翻转这个位。
希望这可以帮助!
你总是可以使用std::bitset
修改位。
或者您可以使用位操作(假设您的意思是第4位计数为1。如果您的意思是从0开始计数,则不要减1)。 请注意,我使用1U
只是为了保证整个操作发生在无符号数字上:
设置: x |= (1U << (4 - 1));
要清除: x &= ~(1U << (4 - 1));
要切换: x ^= (1U << (4 - 1));
要设置第四位, OR
为00001000
(二进制)。
要清除第四位, AND
与11110111
(二进制)。
要切换第四位, XOR
为00001000
(二进制)。
例子:
00110010或00001000 = 00111010
00110010 AND 11110111 = 00110010
00110010 XOR 00001000 = 00111010
简单,因为你拥有或拥有任何价值,
int x = 50;
以编程方式设置第4位(从右侧),
int y = x | 0x00000008;
因为,在数字之前0x
前缀0x
表示它是hexforms。 因此,二进制forms的0x0 = 0000
,二进制forms的0x8=1000
。 这解释了答案。
在C语言中尝试使用其中一个函数来改变n位
char bitfield; // start at 0th position void chang_n_bit(int n, int value) { bitfield = (bitfield | (1 << n)) & (~( (1 << n) ^ (value << n) )); } void chang_n_bit(int n, int value) { bitfield = (bitfield | (1 << n)) & ((value << n) | ((~0) ^ (1 << n))); } void chang_n_bit(int n, int value) { if(value) bitfield |= 1 << n; else bitfield &= ~0 ^ (1 << n); } char print_n_bit(int n) { return (bitfield & (1 << n)) ? 1 : 0; }
您可以使用二进制AND和OR来切换第四位。
要在x上设置第四位,您将使用x |= 1<<3;
, 1<<3
是0b0001左移3位产生0b1000。
要清除x上的第四位,可以使用x &= ~(1<<3);
,在0b00110010(x)和(有效)0b11110111之间的二进制AND,屏蔽x中不在位置4的每个位,从而清除它。