In C++ programming, bit operations are a basic and powerful technology that allows programmers to manipulate data directly at the binary level. This capability is critical to performance optimization, memory savings, and underlying hardware control. This article will explore in-depth mask operation, byte extraction and assembly in C++, and demonstrate the practical application of these technologies through examples.
1. Bit operator basics
Basic bit operators in C++:
- Bitwise and (&): Perform and operation on each bit of the two numbers. Only when the two corresponding bits are 1, the result is 1.
- bitwise or (|): Perform or operate on each bit of two numbers. As long as there is a corresponding bit of 1, the result is 1.
- bitwise xOR (^): Perform an exclusive-OR operation on each bit of two numbers. When the two corresponding bits are different, the result is 1 and 0 when the same bit is .
- Bitwise invert (~): Perform inverse operation on each bit of a number, 0 becomes 1 and 1 becomes 0.
- Move left (<<): Move all bits of a number to the left by the specified number of bits, and add 0 to the right. The left shift is equivalent to performing a multiplication operation of n powers of 2 on the number (n is the number of bits that are moved).
- Move right (>>): Move all bits of a number to the right by the specified number of bits. For unsigned numbers, the high bit is supplemented with 0; for signed numbers, the processing method varies from compiler to compile, and the sign bits may be supplemented (arithm right shift) or 0 (logical right shift).
Example 1: Bitwise and (clear, get the specified bit)
#include <> int main() { int targetValue = 0b11011010; // Binary notation int mask = 0b00110011; int result = targetValue & mask; // Apply the mask, keep the bits of 1 in the mask printf("Original: %08b\n", targetValue); printf("Mask: %08b\n", mask); printf("Result: %08b\n", result); return 0; }
Output:
Original: 11011010
Mask: 00110011
Result: 00011010
Example 2: Bitwise or (retain the specified bit)
#include <> int main() { int a = 0b00101011; int b = 0b10010100; int result = a | b; // Bitwise or operation printf("a: %08b\n", a); printf("b: %08b\n", b); printf("Result: %08b\n", result); return 0; }
Output:
a: 00101011
b: 10010100
Result: 10111111
Example 3: Bitwise XOR (Specific bit flip)
#include <> int main() { int a = 0b01111010; int mask = 0b00001111; int result = a ^ mask; // Bitwise XOR operation, flip the lower 4 bits printf("Original: %08b\n", a); printf("Mask: %08b\n", mask); printf("Result: %08b\n", result); return 0; }
Output:
Original: 01111010
Mask: 00001111
Result: 01110101
Example 4: Inverse
#include <> int main() { int a = 0b01111010; int result = ~a; // Inverse operation printf("Original: %08b\n", a); printf("Result: %08b\n", result); return 0; }
Output:
Original: 01111010
Result: 10000101
Example 5: Move left and right
#include <> int main() { int a = 0b00001111; // 15's binary representation int leftShiftResult = a << 2; // Move left by 2 digits int rightShiftResult = a >> 2; // Right shift 2 bits (logical shift) printf("Original: %08b\n", a); printf("Transfer 2 bits left: %08b\n", leftShiftResult); // It is equivalent to multiplying by 4, and the result is 60 printf("Right shift 2 bits: %08b\n", rightShiftResult); // Equivalent to dividing by 4, the result is 3 or -4 (depending on the sign bit and shift method) return 0; }
Output (assuming logical shift):
Original: 00001111
Move left by 2 bits: 00111100
Move right 2 bits: 00000011
2. Actual mask operation
The mask is a binary number used to mask unwanted bits and only retain the target bits. By operating with & (&), bits of 1 in the mask can be retained, and other bits are cleared. Use mask operations in C/C++ to set, clear and check specific bits of integers. These technologies are very useful in performance optimization, memory savings, and underlying hardware control.
-
Setting specific bits: Through mask and or operation, specific bits of integers can be set. For example, to set the 5th bit of a 32-bit integer (counting from 0), you can use
num | (1 << 5)
。 -
Clear specific bits: Through masking and inversion operations, specific bits of integers can be cleared. For example, to clear the 5th bit of a 32-bit integer, you can use
num & ~(1 << 5)
。 -
Check specific bits: Through the operation, it is possible to check whether the specific bits of the integer are set. For example, to check whether the 5th bit of a 32-bit integer is set, you can use
(num & (1 << 5)) != 0
。
Example 1: Setting a specific bit
Suppose we have a 32-bit integer num, and we want to set the 5th bit (counting from 0). We can use the following code:
#include <> int main() { unsigned int num = 0; // Initialize to 0 unsigned int mask = 1 << 5; // Create a mask, the 5th bit is 1, and the other bits are 0 num |= mask; // Use or operate to set the 5th bit printf("num: %u\n", num); // Output result, you should see that the 5th bit is set to 1 return 0; }
Example 2: Clear a specific bit
Now, suppose we want to clear the 5th position of num. We can use the following code:
#include <> int main() { unsigned int num = 0x20; // Initialize to 0x20 (binary: 00100000), bit 5 is set unsigned int mask = ~(1 << 5); // Create a mask, the 5th bit is 0, and the other bits are 1 num &= mask; // Use and operate to clear the 5th position printf("num: %u\n", num); // Output result, you should see that the 5th bit is cleared return 0; }
Example 3: Check for a specific bit
Finally, suppose we want to check whether the 5th bit of num is set. We can use the following code:
#include <> int main() { unsigned int num = 0x20; // Initialize to 0x20 (binary: 00100000), bit 5 is set unsigned int mask = 1 << 5; // Create a mask, the 5th bit is 1, and the other bits are 0 int bitIsSet = (num & mask) != 0; // Use and operation to check whether the 5th bit is set if (bitIsSet) { printf("The 5th bit is set.\n"); } else { printf("The 5th bit is not set.\n"); } return 0; }
3. Actual battle of byte extraction and assembly
- Byte Extraction: By right shift and mask operations, specific bytes of integers can be extracted.
- Byte Assembly: Multiple bytes can be combined into an integer by shifting left and bitwise or operations.
Byte extraction example
Suppose we have a 32-bit unsigned integernum
, its value is0x12345678
(Hexadecimal representation, binary00010010 00110100 01010110 01111000
)。
Extract the lower 8 bits (minimum byte):
unsigned char lowByte = (unsigned char)(num & 0xFF); printf("Low byte: 0x%02X\n", lowByte); // Output:Low byte: 0x78
here,0xFF
is a mask whose binary representation is11111111
. By and operate&
, we keep itnum
8 bits of the lower and clear the other bits. We then cast the result tounsigned char
type to make sure it is a byte size.
Extract the second byte (counting from 0):
unsigned char secondByte = (unsigned char)((num >> 8) & 0xFF); printf("Second byte: 0x%02X\n", secondByte); // Output:Second byte: 0x56
First, we move the right>> 8
Willnum
All bits of the digits are moved to the right by 8 bits, so that the original second byte becomes the new low byte. Then, we use it again0xFF
Mask and operation to extract this new low byte.
Byte assembly example
Now, suppose we have four bytesbyte1 = 0x12
,byte2 = 0x34
,byte3 = 0x56
,byte4 = 0x78
, we want to combine them into a 32-bit unsigned integer.
Combine two bytes into a 16-bit integer:
unsigned char secondByte = (unsigned char)((num >> 8) & 0xFF); printf("Second byte: 0x%02X\n", secondByte); // Output:Second byte: 0x56
Here, we first move the left operation<< 8
Willbyte1
All bits of the left are 8 bits,byte2
Make room. Then we use bitwise or operation|
Willbyte1
(Move left) andbyte2
Combine it.
Combine four bytes into a 32-bit integer:
unsigned short combined16 = (unsigned short)((byte1 << 8) | byte2); printf("Combined 16-bit: 0x%04X\n", combined16); // Output:Combined 16-bit: 0x1234
Similarly, we willbyte1
、byte2
、byte3
Move 24 bits, 16 bits and 8 bits to the left and then transfer them tobyte4
Combined by bitwise or operation.
4. Introduction to bitset
bitset
It is a very useful class template in the C++ standard library that helps us process binary data efficiently. By usingbitset
, we can conveniently perform bit setting, reset, flip, check, get value and bit calculation operations. also,bitset
It also provides the function of traversing bits set to 1, making processing binary data more flexible and convenient.
Introduce header files and definitionsbitset
#include <bitset> std::bitset<8> myBitset;
Common operations
Setting bit:
useset()
The function can set a bit to 1. For example:
(3); // Will 4 Single position(Index from 0 start)Set as 1
Reset bit:
usereset()
Functions can set a bit to 0. If the call is not covered with parameters, the entirety will be resetbitset
. For example:
(3); // Reset the 4th bit to 0(); // Reset the entire bitset
Flip bit:
useflip()
Functions can flip a bit or the entirebitset
value. If the call is not covered with parameters, the entirety will be flippedbitset
. For example:
(3); // Flip the 4th bit(); // Flip the whole bitset
Check position:
usetest()
Functions can check whether a bit is 1. For example:
bool isBitSet = (3); // If 4 The individual digit is 1,Then return true,否Then return false
Get the value:
useto_string()
Functions can be obtainedbitset
string representation. For example:
std::string bitsetString = myBitset.to_string(); // Return a representation bitset A string of values
Bit operation:
bitset
It also supports some bit operation operations, such as bitwise and bitwise or bitwise, bitwise XOR, etc. For example:
std::bitset<8> anotherBitset("10101010"); myBitset &= anotherBitset; // Perform bitwise and operation
Traversal bit:
usefind_first()
andfind_next()
The function can traverse the bits set to 1. For example:
std::size_t pos = myBitset.find_first(); // Find the index of the first bit set to 1while (pos != std::bitset<8>::npos) { // Process bits set to 1 pos = myBitset.find_next(pos); // Find the index of the next bit set to 1}
V. Other position operation technology
- bit rotation: involves looping the bits of an integer to the left or right. This can be achieved by combining left shift, right shift and bitwise or operations.
- Bit count: Calculate the number of bits set to 1 in an integer. You can use bit-by-bit checking or use more efficient algorithms (such as the Brian Kernighan algorithm).
-
Search: Find the position of the first or last bit in the integer set to 1. You can use bit-by-bit checking or use built-in functions (e.g.
__builtin_ctz
or__builtin_clz
, depending on the compiler). - Bit-fields: Bit fields are a special data structure in C and C++, allowing the definition of bit-level members in the structure. While bit fields are very useful in saving memory space, cross-platform compatibility can be problematic because different compilers handle different ways of layout and filling of bit fields. Therefore, caution is required when using bit fields and ensuring adequate testing is performed on the target platform.
This is the article about C++ bit operation actual mask, extraction and assembly. For more related C++ mask, extraction and assembly content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!