改变一个整数的位

这个问题在这里已经有了答案:

  • 你如何设置,清除和切换一个位? 26个答案

  • 您可以设置数字的第四位,除了第四位以外,其它位置的值都是零。 这可以做到

    x |= (1u << 3);
    

    同样,可以通过将第四位与除第四位以外的值进行AND来清除第四位。 例如:

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

    最后,可以通过将第四位与第四位中除零以外的值进行异或来切换第四位:

    x ^= (1u << 3);
    

    要明白为什么这会起作用,我们需要看两件事情:

  • 在这种情况下, <<运算符的行为是什么?
  • 这里的AND,OR和XOR操作符的行为是什么?
  • 在上述所有三个代码片段中,我们使用<<运算符来生成一个值。 <<运算符是按位左移运算符,它取一个值,然后将其所有位向左移动一些步数。 就你而言,我用过

    1u << 3
    

    取值1(其具有二进制表示1),然后将所有比特移位三个点,用0填充缺失值。这产生了二进制值1000 ,其在第四比特中设置了比特。

    现在,为什么

    x |= (1u << 3);
    

    设置数字的第四位? 这与OR运算符的工作方式有关。 |=运算符类似于+=*=除了按位或 - 它相当于

    x = x | (1u << 3);
    

    那么为什么用二进制值1000对OR进行求和呢? 这与OR的定义方式有关:

    0 | 0  == 0
    0 | 1  == 1
    1 | 0  == 1
    1 | 1  == 1
    

    但更重要的是,我们可以更简洁地将其重写为

    x | 0  == x
    x | 1  == 1
    

    这是一个非常重要的事实,因为它意味着将任意位与0或不改变该位的值,而将任何位与1进行或运算总是将该位设置为1。 这意味着,当我们写作

    x |= (1u << 3);
    

    由于(1u << 3)是除第四位之外的任何地方都为零的值,所以按位OR将除了第四位之外保持x的所有位不变,然后将其设置为1。 更一般地说,将一个数字与一系列零和一个数值进行或运算,将保留所有位为零的值并设置位为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
    

    请注意,这意味着如果我们将两个数字组合在一起,则所得到的值将会使得所有与零相关的位被设置为零,而所有其他位都被保留。 这意味着如果我们和与

    ~(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 (二进制)。

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

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

    例子:

    00110010或00001000 = 00111010

    00110010和11110111 = 00110010

    00110010 XOR 00001000 = 00111010

    链接地址: http://www.djcxy.com/p/28787.html

    上一篇: Change a bit of an integer

    下一篇: Dependency chain analysis