#include <stdio.h>
#include <stdint.h>
uint32_t extract_even_bits(uint32_t reg)
{
uint8_t index = 0;
uint32_t ext_val = 0;
for ( ; index < 32; index+=2)
{
ext_val |= ((reg >> index) & 1) << ((index + 1) / 2);
}
return ext_val;
}
int main() {
uint32_t reg;
scanf("%u", ®);
printf("%u", extract_even_bits(reg));
return 0;
}This code is a bit-manipulation utility that filters and compresses data. It picks out only the bits at even positions (0, 2, 4, ..., 30) from a 32-bit register and packs them together into a new 16-bit result.
Imagine you have a row of 32 lights. This function acts like a sieve that only lets the lights at even-numbered spots pass through, then pushes them all together so there are no gaps between them.
1. The Iteration (index += 2)
The loop starts at index = 0 and jumps by 2 in every step. This automatically skips all the odd-numbered bits (1, 3, 5, etc.) and focuses only on positions $0, 2, 4, \dots, 30$.
2. Isolating the Bit ((reg >> index) & 1)
reg >> index: This brings the bit we are currently interested in down to the "0" position.
& 1: This masks out everything else, leaving us with either a 0 or a 1.
3. Packing the Result (<< ((index + 1) / 2))
This is the most clever part of the code. We don't want the even bits to stay in their original wide-spaced positions. We want to pack them tightly into a new value.
If index = 0: Result is shifted by $(0+1)/2 = 0$. (Goes to bit 0)
If index = 2: Result is shifted by $(2+1)/2 = 1$. (Goes to bit 1)
If index = 4: Result is shifted by $(4+1)/2 = 2$. (Goes to bit 2)
... and so on, until bit 30 of the original becomes bit 15 of the result.
Suppose we have an 8-bit sample (to keep it simple): reg = 170 (Binary: 10101010).
Original Index | Bit Value | Is it Even? | Destination Index |
|---|---|---|---|
| 0 | 0 | Yes | 0 |
| 1 | 1 | No | (Skipped) |
| 2 | 0 | Yes | 1 |
| 3 | 1 | No | (Skipped) |
| 4 | 0 | Yes | 2 |
| 5 | 1 | No | (Skipped) |
| 6 | 0 | Yes | 3 |
| 7 | 1 | No | (Skipped) |
Result: 0000 (Decimal 0). If the input was 01010101 (85), the result would be 1111 (Decimal 15).
Data Compression: This technique is often used in specialized hardware protocols where data is "interleaved" (e.g., bit 0 is Temperature, bit 1 is Pressure, bit 2 is Temperature, bit 3 is Pressure). This function would allow you to extract just the Temperature data.
The Indexing Trick: The formula (index + 1) / 2 (using integer division) effectively maps the sequence $[0, 2, 4, 6...]$ to $[0, 1, 2, 3...]$.
Optimization Note: While the for loop is easy to read, this can also be done without a loop using "bit-shuffling" masks (like Parallel Bit Deposit/Extract instructions on modern CPUs), which would be even faster for high-performance applications.
Input
85
Expected Output
15