Reputation: 10799
I have a table with different codes. And their Id's are powers of 2. (20, 21, 22, 23...). Based on different conditions my application will assign a value to the "Status" variable. for ex :
Status = 272 ( which is 28+ 24)
Status = 21 ( Which is 24+ 22+20)
If Status = 21 then my method (C#) should tell me that 21 is sum of 16 + 4 + 1.
Upvotes: 8
Views: 7048
Reputation: 1763
You can use bitwise operators for this (assuming that you have few enough codes that the values stay in an integer variable).
a & (a - 1)
gives you back a
after unsetting the last set bit. You can use that to get the value of the corresponding flag, like:
while (QStatus) {
uint nxtStatus = QStatus & (QStatus - 1);
processFlag(QStatus ^ nxtStatus);
QStatus = nxtStatus;
}
processFlag
will be called with the set values in increasing order (e.g. 1, 4, 16 if QStatus
is originally 21).
Upvotes: 2
Reputation: 133072
for (uint currentPow = 1; currentPow != 0; currentPow <<= 1)
{
if ((currentPow & QStatus) != 0)
Console.WriteLine(currentPow); //or save or print some other way
}
for QStatus == 21
it will give
1
4
16
Explanation:
A power of 2 has exactly one 1
in its binary representation. We take that one to be the rightmost one(least significant) and iteratively push it leftwards(towards more significant) until the number overflows and becomes 0
. Each time we check that currentPow & QStatus
is not 0.
Upvotes: 16
Reputation: 7672
This is basically binary (because binary is also base 2). You can bitshift values around !
uint i = 87;
uint mask;
for (short j = 0; j < sizeof(uint); j++)
{
mask = 1 << j;
if (i & mask == 1)
// 2^j is a factor
}
Upvotes: 3
Reputation: 217351
You can test all bits in the input value if they are checked:
int value = 21;
for (int i = 0; i < 32; i++)
{
int mask = 1 << i;
if ((value & mask) != 0)
{
Console.WriteLine(mask);
}
}
Output:
1 4 16
Upvotes: 18
Reputation: 69270
This can probably be done much cleaner with an enum with the [Flags]
attribute set.
Upvotes: 5