#include <stdio.h>
#include <stdint.h>
uint32_t extract_even_bits(uint32_t reg) {
uint32_t even_bits = reg & 0x55555555;
even_bits = (even_bits | (even_bits >> 1)) & 0x33333333;
even_bits = (even_bits | (even_bits >> 2)) & 0x0F0F0F0F;
even_bits = (even_bits | (even_bits >> 4)) & 0x00FF00FF;
even_bits = (even_bits | (even_bits >> 8)) & 0x0000FFFF;
return even_bits;
}
int main() {
uint32_t reg;
scanf("%u", ®);
printf("%u", extract_even_bits(reg));
return 0;
}Masking Even Bits:
The process starts by applying a mask (0x55555555) to the input value. This mask has binary 1s at all even positions (0, 2, 4, ..., 30) and 0s elsewhere. By performing a bitwise AND with this mask, we isolate the even bits and set all odd bits to zero.
Packing the Bits:
After masking, the even bits are still spaced out within the 32-bit value. To compress them into consecutive positions, we use a sequence of bitwise ORs and ANDs combined with right shifts. Each step moves the bits closer together:
Result:
The final value contains the original even-positioned bits, now packed together in order, starting from the least significant bit. This approach is highly efficient because it uses a fixed number of operations, regardless of the input, and avoids any loops.
even_bits variable for reg = 0b01010101 (decimal 85):Initial value
reg = 0b01010101
Step 1: Mask Even Bits
even_bits = reg & 0x55555555;
0x55555555 = 01010101 01010101 01010101 0101010101010101even_bits = 0b01010101
Step 2: First Packing
even_bits = (even_bits | (even_bits >> 1)) & 0x33333333;
even_bits >> 1 = 00101010even_bits | (even_bits >> 1) = 011111110x33333333 = 00110011 00110011 00110011 001100110011001101111111 & 00110011 = 00110011even_bits = 0b00110011
Step 3: Second Packing
even_bits = (even_bits | (even_bits >> 2)) & 0x0F0F0F0F;
even_bits >> 2 = 00001100even_bits | (even_bits >> 2) = 001111110x0F0F0F0F = 00001111 00001111 00001111 000011110000111100111111 & 00001111 = 00001111even_bits = 0b00001111
Step 4: Third Packing
even_bits = (even_bits | (even_bits >> 4)) & 0x00FF00FF;even_bits >> 4 = 00000000
even_bits | (even_bits >> 4) = 000011110x00FF00FF = 00000000 11111111 00000000 111111111111111100001111 & 11111111 = 00001111
even_bits = 0b00001111
Step 5: Final Packing
even_bits = (even_bits | (even_bits >> 8)) & 0x0000FFFF;
even_bits >> 8 = 00000000even_bits | (even_bits >> 8) = 000011110x0000FFFF = lower 16 bits set00001111 & 00001111 = 00001111even_bits = 0b00001111
Final Output:0b1111 (decimal 15)
Input
85
Expected Output
15