#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.
Related
I am learning a backtrack problem with memoization using bit-mask.
When checking if the i'th bit is set in a bit-mask, all the solutions I have come across are doing (mask >> i) & 1. I was wondering, why is the & 1 necessary? Isn't (mask >> i) a 1 when the i'th bit is set, and a 0 when the bit is not set? That already translate into true and false.
(mask >> i) cannot eliminate the higher bits.
For example, when mask = 5 (101 in binary) and i = 1, the value of (mask >> i) is 2. This evaluated as true, but the 2nd lowest bit is 0, so you fail to check the bit correctly.
Therefore, & 1 is necessary to eliminate the higher bits and check one specified bit correctly.
For example, if you want to check bit 0 for the mask 0b10 then the expression mask >> 0 yields the same value 0b10, that is not equal to 0. However, its bit 0 is equal to 0. So you need to write ( mask >> 0 ) & 1, or in general ( mask >> i ) & 1.
That is, higher bits that precede the i-th bit can be 1. Thus the expression mask >> i does not change their values. So the value of the expression can be unequal to 0 though the i-th bit itself is equal to 0.
The expression (mask >> i) keeps all the bits from the i-th. That means, if either the i-th, (i+1)-th, etc. is set, then it'll evaluate to true in an if-expression.
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.
Is there a quick bit operation to implement msb_equal: a function to check if two numbers have the same most significant bit?
For example, 0b000100 and 0b000111 both have 4 as their most significant bit value, so they are most msb_equal. In contrast 0b001111 has 8 as the MSB value, and 0b010000 has 16 as it's MSB value, so the pair are not msb_equal.
Similarly, are there fast ways to compute <, and <=?
Examples:
msb_equal(0, 0) => true
msb_equal(2, 3) => true
msb_equal(0, 1) => false
msb_equal(1, 2) => false
msb_equal(3, 4) => false
msb_equal(128, 255) => true
A comment asks why 0 and 1 are not msb_equal. My view on this is that if I write out two numbers in binary, they are msb_equal when the most significant 1 bit in each is the same bit.
Writing out 2 & 3:
2 == b0010
3 == b0011
In this case, the top most 1 is the same in each number
Writing out 1 & 0:
1 == b0001
0 == b0000
Here, the top most 1s are not the same.
It could be said that as 0 has no top most set bit, msb_equal(0,0) is ambiguous. I'm defining it as true: I feel this is helpful and consistent.
Yes, there are fast bit based operations to compute MSB equality and inequalities.
Note on syntax
I'll provide implementations using c language syntax for bitwise and logical operators:
| – bitwise OR. || – logical OR.
& – bitwise AND. && – logical AND.
^ – bitwise XOR.
==
msb_equal(l, r) -> bool
{
return (l^r) <= (l&r)
}
<
This is taken from the Wikipedia page on the Z Order Curve (which is awesome):
msb_less_than(l, r) -> bool
{
(l < r) && (l < l^r)
}
<=
msb_less_than_equal(l, r) -> bool
{
(l < r) || (l^r <= l&r)
}
If you know which number is the smallest/biggest one, there is a very fast way to check whether the MSBs are equal. The following code is written in C:
bool msb_equal(unsigned small, unsigned big) {
assert(small <= big);
return (small ^ big) <= small;
}
This can be useful in cases like when you add numbers to a variable and you want to know when you reached a new power of 2.
Explanation
The trick here is that if the two numbers have the same most significant bit, it will disappear since 1 xor 1 is 0; that makes the xor result smaller than both numbers. If they have different most significant bits, the biggest number's MSB will remain because the smallest number has a 0 in that place and therefore the xor result will be bigger than the smallest number.
When both input numbers are 0, the xor result will be 0 and the function will return true. If you want 0 and 0 to count as having different MSBs then you can replace <= with <.
I saw some code like this:
void testCase2 (int variant)
{
if (variant & 0x1)
{
return;
}
}
What does the & operator mean in the if statement, is it ==? Why to use &?
& is the bitwise AND operator. Given two integer operands, it does an AND operation on each bit position, i.e. in the result only those bits will be set that were set in both operands.
If one of the operands is 0x1 as in this case, the result will be 0x1 if, and only if, that bit is also set in the other operand (here, variant).
As C/C++ considers any non-zero integer to be true,
if (variant & 0x1)
checks if the least-significant bit in variant is set.
Similarly,
if (variant & 0x2)
would check if the second least-significant bit in variant is set, and
if (variant & 0x3)
would check if either of the two least-significant bits in variant is set.
It's a "bitwise and", basically that code will check if the lowest significant bit in 'variant' is set.
The operator does an AND operation on each relative bit of the two items being compared to get the result. It's a common way to examine variables that are being used to carry multiple bit 'flags'.
as an example, "bitwise anding" two variables with these binary representations:
00010001
00000001
would give:
00000001
http://en.wikipedia.org/wiki/Bitwise_operation#AND
variant: 1011 Bitwise AND
0x1 : 0001
-------
0001
-------
Bitwise AND is used to Turn-Off bits.
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.
SRC : refer here
& operator is the boolean arithmetic AND operator i.e. bitwise AND
IN your code block, if (variant & 0x1) is evaluated as:
if (the result of ANDing variant and 0x1) is TRUE, them go inside the following block of code.
Consider the following code (see it in action on IDEONE):
#include <iostream>
using namespace std;
int main() {
int variant = 0x1f; // Declared in HEX format;
if (variant & 0x1){ // If the LSB is 1 i.e. if the
cout << "axious!!!"; // It'll print "axious!!!"
} else
{
cout << "It's something else!!!";
}
return 0;
}
But the following code:
#include <iostream>
using namespace std;
int main() {
int variant = 0x10; // Declared in HEX format;
if (variant & 0x1){ // If the LSB is 1
cout << "axious!!!";
} else
{
cout << "It's something else!!!"; // This will be printed!!
}
return 0;
}
Now remember that 0x1 will be 1 in binary i.e. the LSB will be 1 so you are actually checking for what is the first bit of your variant.
I have this code:
if((bob.prop & 0x100) == 0x100) {
// some code
}
I found that this part:
bob.prop & 0x100
means
is bob.prop set to 0x100?
So, I think it gives me true or false. But the result of this code is comparing with 0x100 also:
if((bob.prop & 0x100) == 0x100) {
What is it? What does it mean?
0x100 in binary is 0000000100000000, which has its 9th bit set.
Doing bob.prop & 0x100 filters out that 9th bit from bob.prop. For example:
bob.prop & 0x100
1010110101110010 & 0000000100000000 gives 0000000100000000
0110110001101011 & 0000000100000000 gives 0000000000000000
It does this because it is the bitwise AND of the two operands. That means the result will only have bits set where bits are set in both of the operands.
You are then checking whether the result is equal to 0000000100000000, which is the same as asking "Was the 9th bit set?"
It is not necessary to perform this final comparison, because any integer value greater than 0 will convert to true, while 0 will convert to false. You could just write:
if(bob.prop & 0x100)
the bob.prop & 0x100 is doing a bitwise and of bob.prop with 0x100. The if statement is ensuring that equals 0x100.
So the first test is evaluating an expression, and putting it in the if checks if it matches 0x100.
Note that you are not testing that bob.prop is set to 0x100, rather than are checking whether one bit is set. So the expression would be true for input of 0x100, 0x101, 0x102, 0xfff, ...