#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 1
s at all even positions (0, 2, 4, ..., 30) and 0
s 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 01010101
01010101
even_bits = 0b01010101
Step 2: First Packing
even_bits = (even_bits | (even_bits >> 1)) & 0x33333333;
even_bits >> 1
= 00101010
even_bits | (even_bits >> 1)
= 01111111
0x33333333
= 00110011 00110011 00110011 00110011
00110011
01111111 & 00110011
= 00110011
even_bits = 0b00110011
Step 3: Second Packing
even_bits = (even_bits | (even_bits >> 2)) & 0x0F0F0F0F;
even_bits >> 2
= 00001100
even_bits | (even_bits >> 2)
= 00111111
0x0F0F0F0F
= 00001111 00001111 00001111 00001111
00001111
00111111 & 00001111
= 00001111
even_bits = 0b00001111
Step 4: Third Packing
even_bits = (even_bits | (even_bits >> 4)) & 0x00FF00FF;even_bits >> 4
= 00000000
even_bits | (even_bits >> 4)
= 00001111
0x00FF00FF
= 00000000 11111111 00000000 11111111
11111111
00001111 & 11111111
= 00001111
even_bits = 0b00001111
Step 5: Final Packing
even_bits = (even_bits | (even_bits >> 8)) & 0x0000FFFF;
even_bits >> 8
= 00000000
even_bits | (even_bits >> 8)
= 00001111
0x0000FFFF
= lower 16 bits set00001111 & 00001111
= 00001111
even_bits = 0b00001111
Final Output:0b1111
(decimal 15)
Input
85
Expected Output
15