How to reverse following bitwise operation (((flags >> 4) & 31) +1) so that I can get value of flags back - bit-manipulation

How to reverse below operation so that I can get value of flags back
(((flags >> 4) & 31) +1)

Related

How would I check for allevenbits in bitwise operations?

Using bitwise operations exclusively, how would I set y to 1 if all even-numbered bits of x are 1, and otherwise y is set to 0 (maximum of 8-bits)?
So far I have as follows:
p = ~x + 1
a = p >> 2
b = p >> 4
c = p >> 6
d = p >> 8
y = [insert code here]
Permitted: 12 operations (may use !, ~, +, -, <<, >>, &, ^, |) and up to 8-bit constants.
You could shift down all bits to the first bit and do a bitwise AND:
#even
y = 1 & (x >> 6) & (x >> 4) & (x >> 2) & x
#odd
y = (x >> 7) & (x >> 5) & (x >> 3) & (x >> 1)
Note the 1 & part for the even case since x >> 6 leaves the 2 MSbs in the result and you only want the low one.
Here's a demonstrative program in written in C:
Demo
Since you mentioned that you may use ! (NOT), a simpler version may be:
#even
!((x & 0b01010101) ^ 0b01010101)
#odd
!((x & 0b10101010) ^ 0b10101010)
Here the constants are first used to filter out the even/odd bits and then XOR with the same. This will produce 0 if all bits were set. Combine with NOT and you'll get 1 if they were all set and 0 if they were not.
Demo

Use of logical AND/OR without conditional/branching

I am trying to write a function that counts some bit flags while avoiding the use of branching or conditionals:
uint8_t count_descriptors(uint8_t n)
{
return
((n & 2) && !(n & 1)) +
((n & 4) && !(n & 1)) +
((n & 8) && !(n & 1)) +
((n & 16) && !(n & 1)) +
((n & 32) && 1 ) +
((n & 64) || (n & 128)) ;
}
Bit zero is not directly counted, but bits 1-4 are only considered if bit 0 is not set, bit 5 is considered unconditionally, bit 6-7 can only counted once.
However, I understand that the boolean && and || use short-circuit evaluation. This means that their use creates a conditional branch, as you would see in such examples: if( ptr != nullptr && ptr->predicate()) that guarantees code in the second sub-expression is not executed if the result is short-circuit evaluated from the first sub-expression.
The first part of the question: do I need to do anything? Since these are purely arithmetic operations with no side-effects, will the compiler create conditional branches?
Second part: I understand that bitwise boolean operators do not short-circuit evaluate, but the only problem the bits do not line up. The result of masking the nth bit is either 2^n or zero.
What is the best way to make an expression such as (n & 16) evaluate to 1 or 0?
I assume with "bit 6-7 can only counted once" you mean only one of them is being counted
In this case something like this should work
uint8_t count_descriptors(uint8_t n)
{
uint8_t retVar;
retVar = (n&1)*(n&2 >> 1) +
(n&1)*(n&4 >> 2) +
(n&1)*(n&8 >> 3) +
(n&1)*(n&16 >> 4) +
(n&32 >> 5) +
(int)((n&64 >> 6) + (n&128 >> 7) >= 1)
return retVar;
}
What is the best way to make an expression such as (n & 16) evaluate
to 1 or 0?
By shifting it right the required number of bits: either (n>>4)&1 or (n&16)>>4.
I'd probably use a lookup table, either for all 256 values, or at least for the group of 4.
nbits[16]={0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4};
//count bits 1..4 iff bit 0 is 0, bit 5 always, and bit 6 or 7
return (!(n&1) * nbits[(n>>1)&0xF]) + ((n>>5)&1) + (((n>>6)|(n>>7))&1)
I think the cleanest way to convert (n & 16) into 0 or 1 is to just use int(bool(n & 16)). The cast to int can be dropped if you are using them in an arithmetic expression (like bool(n & 2) + bool(n & 4)).
For your function of counting bits set I would recommend using the popcount intrinsic function, available as __builtin_popcount on gcc and __popcnt on MSVC. Below is my understanding of the function you described, changed to use popcount.
f(n & 1)
{
//clear out first 4 bits and anything > 255
n &= 0xF0;
}
else
{
//clear out anything > 255 and bottom bit is already clear
n &= 0xFF;
}
return __builtin_popcount(n); //intrinsic function to count the set bits in a number
This doesn't quite match the function you wrote, but hopefully from here you get the idea.

Masking and shifting

Should we first shift the value then mask or the other way? And what is the risk in first masking before shifting?
((loc_Task_value_avg >> 8) & 0x00FF)
OR
((loc_Task_value_avg & 0xFF00) >> 8)
Try working through these kind of examples with real numbers. In this case, you'll find they do not result in the same output.
We'll use two examples.
First, suppose loc_Task_value_avg is equal to 0x1234
((loc_Task_value_avg >> 8) & 0x00FF)
((0x1234 >> 8 ) & 0x00FF)
(0x0012 & 0x00FF)
0x0012
vs
((loc_Task_value_avg & 0xFF00) >> 8)
((0x1234 & 0xFF00) >> 8)
(0x0012 >> 8)
0x0012
The danger comes when we are using signed values. Let's use 0xFEDC.
((loc_Task_value_avg >> 8) & 0x00FF)
((0xFEDC >> 8 ) & 0x00FF)
(0xFFFE & 0x00FF)
0x00FE
vs
((loc_Task_value_avg & 0xFF00) >> 8)
((0xFEDC & 0xFF00) >> 8)
(0xFE00 >> 8)
0xFFFE
The reason we get two separate outputs is because when dealing with signed values (Two's complement), shifting from the highest to lowest order value may result in the sign bit being extended. Whether this happens depends on whether the instructions by the compiler use signed or unsigned shift.
It depends on the size of the value you are shifting, the number of bits in the mask and whether the underlying value is signed or unsigned.
A shift-right is a divide by 2. On a signed value this means the sign bit will be preserved (because the underlying representation is most likely twos compliment). If your shift is large enough to shift copied sign bits into the masked result, it will make a difference.
If the underlying value is unsigned, it doesn't matter whether you shift then mask or mask then shift.
Each case would do different things.
Take the case with bits 1101.
If I mask the second bit (the zero) and then shift it one, then I would have the value 0.
On the other hand, if I shift the bits by one and then mask the second bit, I would have the value 1.
It is important to clearly identify what exactly you are intending to do and then go about from there.

Converting Bitwise Statements in C to Delphi

The following statements in C:
iONE >>= iShift;
iONE &= 0xffefffff;
iONE |= (((((long)(*temp & 0x7f) - 65) << 2) + iShift + 1023) << 20) | (iTWO & 0x80000000);
Is there something like shr=, And= and Or= in Delphi. Is there more appropriate way than literal porting, especially the third statement.
Those are basically two operations combined.
x >>= y means x = x >> y.
The same applies for &= and |=.
And for the Delphi part: And, Or, and Right Shift.

How does this algorithm to count the number of set bits in a 32-bit integer work?

int SWAR(unsigned int i)
{
i = i - ((i >> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
}
I have seen this code that counts the number of bits equals to 1 in 32-bit integer, and I noticed that its performance is better than __builtin_popcount but I can't understand the way it works.
Can someone give a detailed explanation of how this code works?
OK, let's go through the code line by line:
Line 1:
i = i - ((i >> 1) & 0x55555555);
First of all, the significance of the constant 0x55555555 is that, written using the Java / GCC style binary literal notation),
0x55555555 = 0b01010101010101010101010101010101
That is, all its odd-numbered bits (counting the lowest bit as bit 1 = odd) are 1, and all the even-numbered bits are 0.
The expression ((i >> 1) & 0x55555555) thus shifts the bits of i right by one, and then sets all the even-numbered bits to zero. (Equivalently, we could've first set all the odd-numbered bits of i to zero with & 0xAAAAAAAA and then shifted the result right by one bit.) For convenience, let's call this intermediate value j.
What happens when we subtract this j from the original i? Well, let's see what would happen if i had only two bits:
i j i - j
----------------------------------
0 = 0b00 0 = 0b00 0 = 0b00
1 = 0b01 0 = 0b00 1 = 0b01
2 = 0b10 1 = 0b01 1 = 0b01
3 = 0b11 1 = 0b01 2 = 0b10
Hey! We've managed to count the bits of our two-bit number!
OK, but what if i has more than two bits set? In fact, it's pretty easy to check that the lowest two bits of i - j will still be given by the table above, and so will the third and fourth bits, and the fifth and sixth bits, and so and. In particular:
despite the >> 1, the lowest two bits of i - j are not affected by the third or higher bits of i, since they'll be masked out of j by the & 0x55555555; and
since the lowest two bits of j can never have a greater numerical value than those of i, the subtraction will never borrow from the third bit of i: thus, the lowest two bits of i also cannot affect the third or higher bits of i - j.
In fact, by repeating the same argument, we can see that the calculation on this line, in effect, applies the table above to each of the 16 two-bit blocks in i in parallel. That is, after executing this line, the lowest two bits of the new value of i will now contain the number of bits set among the corresponding bits in the original value of i, and so will the next two bits, and so on.
Line 2:
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
Compared to the first line, this one's quite simple. First, note that
0x33333333 = 0b00110011001100110011001100110011
Thus, i & 0x33333333 takes the two-bit counts calculated above and throws away every second one of them, while (i >> 2) & 0x33333333 does the same after shifting i right by two bits. Then we add the results together.
Thus, in effect, what this line does is take the bitcounts of the lowest two and the second-lowest two bits of the original input, computed on the previous line, and add them together to give the bitcount of the lowest four bits of the input. And, again, it does this in parallel for all the 8 four-bit blocks (= hex digits) of the input.
Line 3:
return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
OK, what's going on here?
Well, first of all, (i + (i >> 4)) & 0x0F0F0F0F does exactly the same as the previous line, except it adds the adjacent four-bit bitcounts together to give the bitcounts of each eight-bit block (i.e. byte) of the input. (Here, unlike on the previous line, we can get away with moving the & outside the addition, since we know that the eight-bit bitcount can never exceed 8, and therefore will fit inside four bits without overflowing.)
Now we have a 32-bit number consisting of four 8-bit bytes, each byte holding the number of 1-bit in that byte of the original input. (Let's call these bytes A, B, C and D.) So what happens when we multiply this value (let's call it k) by 0x01010101?
Well, since 0x01010101 = (1 << 24) + (1 << 16) + (1 << 8) + 1, we have:
k * 0x01010101 = (k << 24) + (k << 16) + (k << 8) + k
Thus, the highest byte of the result ends up being the sum of:
its original value, due to the k term, plus
the value of the next lower byte, due to the k << 8 term, plus
the value of the second lower byte, due to the k << 16 term, plus
the value of the fourth and lowest byte, due to the k << 24 term.
(In general, there could also be carries from lower bytes, but since we know the value of each byte is at most 8, we know the addition will never overflow and create a carry.)
That is, the highest byte of k * 0x01010101 ends up being the sum of the bitcounts of all the bytes of the input, i.e. the total bitcount of the 32-bit input number. The final >> 24 then simply shifts this value down from the highest byte to the lowest.
Ps. This code could easily be extended to 64-bit integers, simply by changing the 0x01010101 to 0x0101010101010101 and the >> 24 to >> 56. Indeed, the same method would even work for 128-bit integers; 256 bits would require adding one extra shift / add / mask step, however, since the number 256 no longer quite fits into an 8-bit byte.
I prefer this one, it's much easier to understand.
x = (x & 0x55555555) + ((x >> 1) & 0x55555555);
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
x = (x & 0x0f0f0f0f) + ((x >> 4) & 0x0f0f0f0f);
x = (x & 0x00ff00ff) + ((x >> 8) & 0x00ff00ff);
x = (x & 0x0000ffff) + ((x >> 16) &0x0000ffff);
This is a comment to Ilamari's answer.
I put it as an answer because of format issues:
Line 1:
i = i - ((i >> 1) & 0x55555555); // (1)
This line is derived from this easier to understand line:
i = (i & 0x55555555) + ((i >> 1) & 0x55555555); // (2)
If we call
i = input value
j0 = i & 0x55555555
j1 = (i >> 1) & 0x55555555
k = output value
We can rewrite (1) and (2) to make the explanation clearer:
k = i - j1; // (3)
k = j0 + j1; // (4)
We want to demonstrate that (3) can be derived from (4).
i can be written as the addition of its even and odd bits (counting the lowest bit as bit 1 = odd):
i = iodd + ieven =
= (i & 0x55555555) + (i & 0xAAAAAAAA) =
= (i & modd) + (i & meven)
Since the meven mask clears the last bit of i,
the last equality can be written this way:
i = (i & modd) + ((i >> 1) & modd) << 1 =
= j0 + 2*j1
That is:
j0 = i - 2*j1 (5)
Finally, replacing (5) into (4) we achieve (3):
k = j0 + j1 = i - 2*j1 + j1 = i - j1
This is an explanation of yeer's answer:
int SWAR(unsigned int i) {
i = (i & 0x55555555) + ((i >> 1) & 0x55555555); // A
i = (i & 0x33333333) + ((i >> 2) & 0x33333333); // B
i = (i & 0x0f0f0f0f) + ((i >> 4) & 0x0f0f0f0f); // C
i = (i & 0x00ff00ff) + ((i >> 8) & 0x00ff00ff); // D
i = (i & 0x0000ffff) + ((i >> 16) &0x0000ffff); // E
return i;
}
Let's use Line A as the basis of my explanation.
i = (i & 0x55555555) + ((i >> 1) & 0x55555555)
Let's rename the above expression as follows:
i = (i & mask) + ((i >> 1) & mask)
= A1 + A2
First, think of i not as 32 bits, but rather as an array of 16 groups, 2 bits each. A1 is the count array of size 16, each group containing the count of 1s at the right-most bit of the corresponding group in i:
i = yx yx yx yx yx yx yx yx yx yx yx yx yx yx yx yx
mask = 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
i & mask = 0x 0x 0x 0x 0x 0x 0x 0x 0x 0x 0x 0x 0x 0x 0x 0x
Similarly, A2 is "counting" the left-most bit for each group in i. Note that I can rewrite A2 = (i >> 1) & mask as A2 = (i & mask2) >> 1:
i = yx yx yx yx yx yx yx yx yx yx yx yx yx yx yx yx
mask2 = 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
(i & mask2) = y0 y0 y0 y0 y0 y0 y0 y0 y0 y0 y0 y0 y0 y0 y0 y0
(i & mask2) >> 1 = 0y 0y 0y 0y 0y 0y 0y 0y 0y 0y 0y 0y 0y 0y 0y 0y
(Note that mask2 = 0xaaaaaaaa)
Thus, A1 + A2 adds the counts of the A1 array and A2 array, resulting in an array of 16 groups, each group now contains the count of bits in each group.
Moving onto Line B, we can rename the line as follows:
i = (i & 0x33333333) + ((i >> 2) & 0x33333333)
= (i & mask) + ((i >> 2) & mask)
= B1 + B2
B1 + B2 follows the same "form" as A1 + A2 from before. Think of i no longer as 16 groups of 2 bits, but rather as 8 groups of 4 bits. So similar to before, B1 + B2 adds the counts of B1 and B2 together, where B1 is the counts of 1s in the right side of the group, and B2 is the counts of the left side of the group. B1 + B2 is thus the counts of bits in each group.
Lines C through E now become more easily understandable:
int SWAR(unsigned int i) {
// A: 16 groups of 2 bits, each group contains number of 1s in that group.
i = (i & 0x55555555) + ((i >> 1) & 0x55555555);
// B: 8 groups of 4 bits, each group contains number of 1s in that group.
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
// C: 4 groups of 8 bits, each group contains number of 1s in that group.
i = (i & 0x0f0f0f0f) + ((i >> 4) & 0x0f0f0f0f);
// D: 2 groups of 16 bits, each group contains number of 1s in that group.
i = (i & 0x00ff00ff) + ((i >> 8) & 0x00ff00ff);
// E: 1 group of 32 bits, containing the number of 1s in that group.
i = (i & 0x0000ffff) + ((i >> 16) &0x0000ffff);
return i;
}