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对象?
下一篇: 你如何设置,清除和切换一个位?