Modern C++:Efficient and Scalable Application Development
上QQ阅读APP看书,第一时间看更新

Bitwise Operators

Integers can be regarded as a series of bits, 0 or 1. Bitwise operators act upon these bits compared to the bit in the same position in the other operand. Signed integers use a bit to indicate the sign, but bitwise operators act on every bit in an integer, so it is usually only sensible to use them on unsigned integers. In the following, all the types are marked as unsigned, so they are treated as not having a sign bit.

The & operator is bitwise AND, which means that each bit in the left-hand operand is compared with the bit in the right-hand operand in the same position. If both are 1, the resultant bit in the same position will be 1; otherwise, the resultant bit is zero:

    unsigned int a = 0x0a0a; // this is the binary 0000101000001010 
unsigned int b = 0x00ff; // this is the binary 0000000000001111
unsigned int c = a & b; // this is the binary 0000000000001010
std::cout << std::hex << std::showbase << c << std::endl;

In this example, using bitwise & with 0x00ff has the same effect as providing a mask that masks out all but the lowest byte.

The bitwise OR operator | will return a value of 1 if either or both bits in the same position are 1, and a value of 0 only if both are 0:

    unsigned int a = 0x0a0a; // this is the binary 0000101000001010 
unsigned int b = 0x00ff; // this is the binary 0000000000001111
unsigned int c = a & b; // this is the binary 0000101000001111
std::cout << std::hex << std::showbase << c << std::endl;

One use of the & operator is to find if a particular bit (or a specific collection of bits) is set:

    unsigned int flags = 0x0a0a; // 0000101000001010 
unsigned int test = 0x00ff; // 0000000000001111

// 0000101000001111 is (flags & test)
if ((flags & test) == flags)
{
// code for when all the flags bits are set in test
}
if ((flags & test) != 0)
{
// code for when some or all the flag bits are set in test
}

The flags variable has the bits we require, and the test variable is a value that we are examining. The value (flags & test) will have only those bits in the test variables that are also set in flags. Thus, if the result is non-zero, it means that at least one bit in test is also set in flags; if the result is exactly the same as the flags variable then all the bits in flags are set in test.

The exclusive OR operator ^ is used to test when the bits are different; the resultant bit is 1 if the bits in the operands are different, and 0 if they are the same. Exclusive OR can be used to flip specific bits:

    int value = 0xf1; 
int flags = 0x02;
int result = value ^ flags; // 0xf3
std::cout << std::hex << result << std::endl;

The final bitwise operator is the bitwise complement ~. This operator is applied to a single integer operand and returns a value where every bit is the complement of the corresponding bit in the operand; so if the operand bit is 1, the bit in the result is 0, and if the bit in the operand is 0, the bit in the result is 1. Note that all bits are examined, so you need to be aware of the size of the integer.