Extract Even Bits Only from 32-bit Register

Code

#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", &reg);
    printf("%u", extract_even_bits(reg));
    return 0;
}

Solving Approach

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.

The "Sieve and Pack" Logic

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.

Step-by-Step Example

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

Yes0
11No(Skipped)
2

0

Yes1
31No(Skipped)
4

0

Yes2
51No(Skipped)
6

0

Yes3
71No(Skipped)

Result: 0000 (Decimal 0). If the input was 01010101 (85), the result would be 1111 (Decimal 15).

Key Takeaways for Others

  • 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.

Upvote
Downvote
Loading...

Input

85

Expected Output

15