改变一个整数

我们有一个整数

int x = 50; 

在二进制中,它是

 00110010 

如何以编程方式更改第四(第4)位?

除了第四位之外,您可以通过将其与除零之外的零值进行或运算来设置数字的第四位。 这可以做到

 x |= (1u << 3); 

类似地,您可以通过使用除了第四位之外的任何位置的值进行AND运算来清除第四位。 例如:

 x &= ~(1u << 3); 

最后,你可以通过对第四位进行异或来切换,除了第四位之外,其值为零:

 x ^= (1u << 3); 

要了解其工作原理,我们需要考虑两件事:

  1. 在这种情况下<<运算符的行为是什么?
  2. 这里的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));

要设置第四位, OR00001000 (二进制)。

要清除第四位, AND11110111 (二进制)。

要切换第四位, XOR00001000 (二进制)。

例子:

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的每个位,从而清除它。