-4

suppose I want to apply mask 11d to unsigned int starting at position k (in that unsigned int). how can this be implemented?

I wrote a function that implements this, maybe it will be useful to someone

#include <stdio.h>
#include <limits.h>

#define BITS_PER_INT (CHAR_BIT * sizeof(unsigned int))

unsigned int set_bitmask_from_k_position(unsigned int x, int k, unsigned int pattern)
{
    int nbits;
    unsigned int tmp;
    for (nbits = 0, tmp = pattern; tmp > 0; tmp /= 2, nbits++); 
    unsigned int mask = 0;
    mask|=mask | ((~0u << (k+nbits-1))|(~0u >> (BITS_PER_INT-k+1)));
    x &= mask;
    mask = pattern << (k - 1);
    x |= mask;
    return x;
}
int main(void)
{
    printf("0x%X\n", set_bitmask_from_k_position(0x12345678u, 12, 11));
}

I answered my own question myself, thanks to everyone who helped and even those who downgraded my question, I did not find such a question on stackowerflow, so I asked

Ivan Ivanovich
  • 880
  • 1
  • 6
  • 15

1 Answers1

2

Make a bit mask for the number of bits from 12 to 15 (inclusive) by generating the value 215−12+1−1:

unsigned mask = (1u << (15-12+1)) - 1u;

Move the mask to bits 12 to 15:

mask <<= 12;

Use the mask to turn off bits 12 to 15 in x:

x &= ~mask;

Put 11 in those bits:

x |= 11 << 12;

Do it in one step:

x = x & ~( ((1u << (15-12+1)) - 1u) << 12 ) | (11 < 12);

I might also write it as:

x = x & ~( (2u<<15) - (1u<<12) ) | (11 < 12);

because the 2u<<15 combines the +1 into the shift and avoids a problem with C semantics if we want to use a field reaching the highest bit in an unsigned.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312