I am new to C programming and not sure that there is already a good explanation for how to do this, if so I am sorry. I am trying to set the bits within a range given to me.
If its inclusive
mask = ~(~0 << (end - start + 1));
value = (n >> start) & mask;
where n is the original integer, and value is the extracted bits.
Here are some simple examples of shifting and creating masks to motivate the more general expression.
1 == 00001b
1<<2 == 00100b
(1<<2)-1 == 00011b
((1<<2)-1)<<2 == 01100b
So,
((1<<(high-low+1))-1)<<low
This was my solution: The if statements at the front just cover conditionals about low and high. This is passing all the tests I was given.
unsigned int setBits(int low, int high, unsigned int source)
{
if (low < 0) {return source;}
else if (high > 31) {return source;}
else if (low > high) {return source;}
else {
unsigned int mask = 0xFFFFFFFF << (31 - high);
mask = mask >> ((31 - high) + low);
mask = mask << low;
return source | mask;
}
}
2 approaches: Iterative method to set bit in source
from low
to high
:
unsigned int setBitsI(int low, int high, unsigned int source) {
while (low <= high) {
source |= 1u << low;
low++;
}
return source;
}
Non-iterative method:
unsigned int setBitsNI(int low, int high, unsigned int source) {
unsigned setmask = 1u << (high - low);
setmask <<= 1;
setmask--;
setmask <<= low;
return source | setmask;
}
Important to avoid 1u << (1u + high - low)
for when high
is "bit-width-1" and low
is 0, 1u << bit_width
is UB.
Should low
or high
have an value outside the bit range, problems occur.