Reputation: 65
Given an integer
I
and a bitmaskM
, get the corresponding value ofM
fromI
. For example, IfI
is0x11111
andM
is0xff0
the corresponding value is0x11
I can do it by :
&
operation between I
and M
But this way is a little slow, especially step 2. I want a more efficient method for solving this problem.
Upvotes: 3
Views: 214
Reputation: 1724
I don't know if there are more efficient ways to do it. I've always done like you. However, consider that usually the computation of how many bits to right shift (your 2nd step) can be done with a single CPU instruction. It has to be done with instinsic instructions, depending on your system.
On Windows, this operation is provided by _BitScanForward(), while on GCC it is provided by __builtin_ctz().
See this answer for more details.
For example, a possible Windows implementation of your problem could be:
#include <Windows.h>
unsigned int maskandshift(unsigned int m, unsigned int i) {
unsigned int shift;
// _BitScanForward returns 0 if the mask is zero.
// You may prefer the actual number of 0, here:
if (m == 0)
shift = sizeof(i) * CHAR_BIT;
else {
DWORD trailing_zero;
_BitScanForward(&trailing_zero, (DWORD)m);
shift = (unsigned int)trailing_zero;
}
return (m & i) >> shift;
}
In Release configuration, this function is compiled to a check for zero, followed by just 3 assembly instructions in a x64 machine (BSF
, AND
and SHR
).
Upvotes: 1