summaryrefslogtreecommitdiff
path: root/ch2/2-6.c
blob: 09322065073b1f2d91d1338a8a94a94db07aaa95 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include<stdio.h>

/*
 * Set n bits in x starting at position p to rightmost n bits of y.
 */

unsigned setbits(unsigned x, unsigned p, unsigned n, unsigned y) {
    p++;                                            // We're actually interested in p+1.
    unsigned offset = (p - n);                      // Calculate offset of y bits being inserted into x.
    unsigned lower_x = x & ~(~0 << offset);         // Grab LSBs of x to save.
    unsigned y_mask = (y & ~(~0 << n)) << offset;   // Grab pattern from LSBs of y.
    x = x >> p << p;                                // Just keep MSBs of x.
    return x | y_mask | lower_x;                    // Concatenate MSBs of x with LSB pattern from y with LSBs of x.
}

int main() {
    printf("%x\n", setbits(0xaa, 3, 3, 0x33));
    printf("%x\n", setbits(0x00, 3, 3, 0xff));
}