branchless bitwise operation - bit-manipulation

I'm looking for a branchless bitwise operation that can determine with a given mask :
Mask : 0xFF0000 Value : 0xAA0000 return : true
Mask : 0xFF0000 Value : 0xAA00AA return : false
Mask : 0xFF00FF Value : 0xBB00AA return : true
Mask : 0xFF00FF Value : 0x0000AA return : false
Mask : 0xFF00FF Value : 0xAA0000 return : false
Mask : 0xFF00FF Value : 0x0A00AA return : true
That's is : it must returns true if :
the mask has a byte set to 0, the value must have the same byte to 0.
the mask has a byte set to > 0, the value must have the same byte
different of 0.
Edit :
0xFFFF00 and 0x00AA00 should not match.
If the mask has a byte > 0, the value must have the same byte > 0.
That's is : If the mask has this pattern [XX][00][XX], the value must have the same. Where XX can be from 01 to FF in the value.
Thanks!

I'm assuming that we're only dealing with the low-order three bytes, as per the question.
A simple solution (17 operations):
((mask & 0x0000FF) == 0) == ((value & 0x0000FF) == 0) &&
((mask & 0x00FF00) == 0) == ((value & 0x00FF00) == 0) &&
((mask & 0xFF0000) == 0) == ((value & 0xFF0000) == 0)
A better solution (9 operations):
(((mask & 0x7F7F7F) + 0x7F7F7F | mask) & 0x808080) ==
(((value & 0x7F7F7F) + 0x7F7F7F | value) & 0x808080)
A third solution (9 operations):
!((((mask & 0x7F7F7F) + 0x7F7F7F | mask) ^
((value & 0x7F7F7F) + 0x7F7F7F | value)) & 0x808080)
The third solution can be reduced to 8 operations by dropping the ! surrounding the entire expression if your code is prepared to handle zero as pass and non-zero as fail.

Related

Defijne meaning of statement in C++

I am working with some C++ code and I am just a novice and I do not understand what this conditional statement means for a true or false result.
This is what I have:
Font contains values related to bitmap font
for(j = 0; j < COUNT; j++) {
for(i = 0; i < 8; i++) {
Font[j][i] <<= 1;
if((j != COUNT -1) && (Font[j + 1][i] & 0x80))
Font[j][i] |= 0x01;
}
}
I understand most of this, the Boolean &&, then the & is confusing me for relevancy in this use and then the lone 0x80, I just don't understand how that relates to the (Font[j + 1][i] & 0x80) 0x80 is 128 decimal...
The font is a 128 x 8 font, but is that a relationship?
Can someone help me put this together so that I can understand how it is providing the condition?
I also need to know how |= 0x01 affects Font[j][i]. Is that a form of piping?
The if statement generic format is
if (conditional_expression) ...
The conditional_expression is any expression which yields a result. The result zero (0) is false, and anything non-zero is true.
If the conditional_expression is simple and without any kind of comparison, then it's implicitly compared to zero. For example
int my_variable = ...; // Actual value irrelevant for example
if (my_variable) { ... }
The if statement above is implicitly equal to
if (my_variable != 0) { ... }
This implicit comparison to zero is also done for compound conditions, for example
if (some_condition && my_variable) { ... }
is equal to
if (some_condition && my_variable != 0) { ... }
Now we get back to your code and the condition:
if((j != COUNT -1) && (Font[j + 1][i] & 0x80))
With the implicit comparison against zero, the above is equal to
if((j != COUNT -1) && (Font[j + 1][i] & 0x80) != 0)
That is, the right-hand side of the && check is Font[j + 1][i] & 0x80 is zero or not.
As for the & operator itself, it's the bitwise AND, and in essence can be used to check if a bit is set or not. For your code it checks if the bit corresponding to the value 0x80 (the eight bit) is set.

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.

How can I test if all bits are set or all bits are not?

Using bitwise operator how can I test if the n least significant bits of an integer are either all sets or all not sets.
For example if n = 3 I only care about the 3 least significant bits the test should return true for 0 and 7 and false for all other values between 0 and 7.
Of course I could do if x = 0 or x = 7, but I would prefer something using bitwise operators.
Bonus points if the technique can be adapted to take into accounts all the bits defined by a mask.
Clarification :
If I wanted to test if bit one or two is set I could to if ((x & 1 != 0) && (x & 2 != 0)). But I could do the "more efficient" if ((x & 3) != 0).
I'm trying to find a "hack" like this to answer the question "Are all bits of x that match this mask all set or all unset?"
The easy way is if ((x & mask) == 0 || (x & mask) == mask). I'd like to find a way to do this in a single test without the || operator.
Using bitwise operator how can I test if the n least significant bits of an integer are either all sets or all not sets.
To get a mask for the last n significant bits, thats
(1ULL << n) - 1
So the simple test is:
bool test_all_or_none(uint64_t val, uint64_t n)
{
uint64_t mask = (1ULL << n) - 1;
val &= mask;
return val == mask || val == 0;
}
If you want to avoid the ||, we'll have to take advantage of integer overflow. For the cases we want, after the &, val is either 0 or (let's say n == 8) 0xff. So val - 1 is either 0xffffffffffffffff or 0xfe. The failure causes are 1 thru 0xfe, which become 0 through 0xfd. Thus the success cases are call at least 0xfe, which is mask - 1:
bool test_all_or_none(uint64_t val, uint64_t n)
{
uint64_t mask = (1ULL << n) - 1;
val &= mask;
return (val - 1) >= (mask - 1);
}
We can also test by adding 1 instead of subtracting 1, which is probably the best solution (here once we add one to val, val & mask should become either 0 or 1 for our success cases):
bool test_all_or_none(uint64_t val, uint64_t n)
{
uint64_t mask = (1ULL << n) - 1;
return ((val + 1) & mask) <= 1;
}
For an arbitrary mask, the subtraction method works for the same reason that it worked for the specific mask case: the 0 flips to be the largest possible value:
bool test_all_or_none(uint64_t val, uint64_t mask)
{
return ((val & mask) - 1) >= (mask - 1);
}
How about?
int mask = (1<<n)-1;
if ((x&mask)==mask || (x&mask)==0) { /*do whatever*/ }
The only really tricky part is the calculation of the mask. It basically just shifts a 1 over to get 0b0...0100...0 and then subtracts one to make it 0b0...0011...1.
Maybe you can clarify what you wanted for the test?
Here's what you wanted to do, in one function (untested, but you should get the idea). Returns 0 if the n last bits are not set, 1 if they are all set, -1 otherwise.
int lastBitsSet(int num, int n){
int mask = (1 << n) - 1; //n 1-s
if (!(num & mask)) //we got all 0-s
return 0;
if (!(~num & mask)) //we got all 1-s
return 1;
else
return -1;
}
To test if all aren't set, you just need to mask-in only the bits you want, then you just need to compare to zero.
The fun starts when you define the oposite function by just inverting the input :)
//Test if the n least significant bits arent set:
char n_least_arent_set(unsigned int n, unsigned int value){
unsigned int mask = pow(2, n) - 1; // e. g. 2^3 - 1 = b111
int masked_value = value & mask;
return masked_value == 0; // if all are zero, the mask operation returns a full-zero.
}
//test if the n least significant bits are set:
char n_least_are_set(unsigned int n, unsigned int value){
unsigned int rev_value = ~value;
return n_least_arent_set(n, rev_value);
}

What is the difference between 'and' and '&' in C++?

#include <iostream>
int main(int argc, char* argv[])
{
unsigned long mask = 0x00000001;
unsigned long mask1 = 0x00000001;
unsigned long mask2 = 0x00000010;
if ((mask and mask1) && (mask and mask2))// CONDITION_1 is True.
std::cout << "Ohhhhhhh..." << std::endl;
if ((mask & mask1) && (mask & mask2)) //CONDITION_2 is False.
std::cout << "No Output..." << std::endl;
return 0;
}
I think CONDITION_1 and CONDITION_2 both are False, but my thinking is wrong obviously , why 'and' and '&' are not same in C++?
and and && are the same. It's logical and. & is bitwise and.
and or && is the logical AND operator. It yields true if both operands convert to true.
bitand or & is the bitwise AND operator. Each bit of the result is set if the corresponding bits of both operands are set.
The single ampersand is a bitwise and while the 'and' keyword is an alternative for &&, a logical and.
&& and and are both logical and operators, while & is the bitwise and operator.
So
(mask and mask1) && (mask and mask2)
is equivalent to
(mask && mask1) && (mask && mask2)
The 2 "and" operators in C/C++ are && (logical and) and & (bitwise and).
&& will return a boolean result (true/false, 1/0) if both arguments are non-zero (true) and false otherwise. This is used to determine if 2 boolean conditions are BOTH true.
& will return a integer with any bits set (1) in both arguments. So 0b10101010 & 0b11110000 will produce 0b10100000. This is useful for checking flags, or any other uses for bitmasks (especially in the embedded world, where you might use individual bits instead of full bytes/words/dwords for flags).
Edit: learned something new and removed an incorrect statement.
AND is logical short circuit && , while & is bitwise operator , working on individual bits.
When using the logical operators, C++ only evaluates what is necessary from left to right to come up with the combined relational result, ignoring the rest.
Bitwise operators modify variables considering the bit patterns that represent the values they store.
Here is some documentation.
& is the binary AND operator.
The result of this operator has only those bits set to 1 that are 1 in both arguments.
The result of ((mask and mask1) && (mask and mask2):
mask and mask1 == true (== mask && mask1)
mask and mask2 == true (== mask && mask2)
(true) && (true) == true
The result of (mask & mask1) && (mask & mask2):
mask & mask1 == 0x00000001 (since the least significant bit is 1 in both cases)
mask & mask2 == 0x00000000 (the bits that are 1 in mask are 0 in mask2 and vice versa)
(0x00000001) && (0x00000000) == false
AND is equivalent to && which is regarded as logical operator. And & is bitwise operator.
Bitwise AND(&)
The bitwise AND operator is a single ampersand: &. A handy mnemonic is that the small version of the boolean AND, &&, works on smaller pieces (bits instead of bytes, chars, integers, etc). In essence, a binary AND simply takes the logical AND of the bits in each position of a number in binary form.
For instance, working with a byte (the char type):
01001000
&
10111000
--------
00001000
The most significant bit of the first number is 0, so we know the most significant bit of the result must be 0; in the second most significant bit, the bit of second number is zero, so we have the same result. The only time where both bits are 1, which is the only time the result will be 1, is the fifth bit from the left. Consequently,
72 & 184 = 8
Logical AND(&&)
The logical AND operator is used to test whether both conditions are true. If both conditions are true, logical AND returns true. Otherwise, it returns false.

how to add two bits into a hex

I have two bytes and I am setting different bits in order to get different combinations.
E.g, byte 1 bit 7 and byte 2 bit 1,bit 2 makes a combination device ready.
Now, I have created mask
#define C1_device_ready (0x80 | 0x100 | 0x200)
Then I read the data and try to compare.
for 1 byte I can do (data[0] & mask == mask).
But how can I compute it for C1_device_ready mask where there are two bytes, data[0]
and data[1].
Is it easily possible or should I do masking only in single byte.
::added::data is unsigned char data[2]
If data is an array of unsigned char, you could test
if ((data[0] & mask) == (mask & 0xFF) && (data[1] & mask) == ((mask >> 8) & 0xFF))
or combine the two data[i] and check
if (((data[0] | (data[1] << 8)) & mask) == mask)
Use
if (((data[0] | (data[1] << 8)) & mask) == mask) {
// do something
}
((data[0] | (data[1]<<8)) & mask) == mask
should work. Might need to cast things as unsigned int
Try:
if ((*(short *)data) & C1_device_ready)