How do you set, clear, and toggle a single bit?

你如何在C / C ++中设置,清除和切换一点?


Setting a bit

Use the bitwise OR operator ( | ) to set a bit.

number |= 1UL << x;

That will set bit x .

Use 1ULL if number is wider than unsigned long ; promotion of 1UL << x doesn't happen until after evaluating 1UL << x where it's undefined behaviour to shift by more than the width of a long . The same applies to all the rest of the examples.

Clearing a bit

Use the bitwise AND operator ( & ) to clear a bit.

number &= ~(1UL << x);

That will clear bit x . You must invert the bit string with the bitwise NOT operator ( ~ ), then AND it.

Toggling a bit

The XOR operator ( ^ ) can be used to toggle a bit.

number ^= 1UL << x;

That will toggle bit x .

Checking a bit

You didn't ask for this, but I might as well add it.

To check a bit, shift the number x to the right, then bitwise AND it:

bit = (number >> x) & 1U;

That will put the value of bit x into the variable bit .

Changing the nth bit to x

Setting the n th bit to either 1 or 0 can be achieved with the following on a 2's complement C++ implementation:

number ^= (-x ^ number) & (1UL << n);

Bit n will be set if x is 1 , and cleared if x is 0 . If x has some other value, you get garbage. x = !!x will booleanize it to 0 or 1.

To make this independent of 2's complement negation behaviour (where -1 has all bits set, unlike on a 1's complement or sign/magnitude C++ implementation), use unsigned negation.

number ^= (-(unsigned long)x ^ number) & (1UL << n);

or

unsigned long newbit = !!x;    // Also booleanize to force 0 or 1
number ^= (-newbit ^ number) & (1UL << n);

It's generally a good idea to use unsigned types for portable bit manipulation.

It's also generally a good idea to not to copy/paste code in general and so many people use preprocessor macros (like the community wiki answer further down) or some sort of encapsulation.


Using the Standard C++ Library: std::bitset<N> .

Or the Boost version: boost::dynamic_bitset .

There is no need to roll your own:

#include <bitset>
#include <iostream>

int main()
{
    std::bitset<5> x;

    x[1] = 1;
    x[2] = 0;
    // Note x[0-4]  valid

    std::cout << x << std::endl;
}

[Alpha:] > ./a.out
00010

The Boost version allows a runtime sized bitset compared with a standard library compile-time sized bitset.


The other option is to use bit fields:

struct bits {
    unsigned int a:1;
    unsigned int b:1;
    unsigned int c:1;
};

struct bits mybits;

defines a 3-bit field (actually, it's three 1-bit felds). Bit operations now become a bit (haha) simpler:

To set or clear a bit:

mybits.b = 1;
mybits.c = 0;

To toggle a bit:

mybits.a = !mybits.a;
mybits.b = ~mybits.b;
mybits.c ^= 1;  /* all work */

Checking a bit:

if (mybits.c)  //if mybits.c is non zero the next line below will execute

This only works with fixed-size bit fields. Otherwise you have to resort to the bit-twiddling techniques described in previous posts.

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

上一篇: 如何遍历或枚举JavaScript对象?

下一篇: 你如何设置,清除和切换一个位?