What does this & operator mean here? - c++

I was reading some tutorial about openGL in qt.
One of the mouse event slot has this code in it:
if (event->buttons() & Qt::LeftButton) {
rotationX += 180 * dy;
rotationY += 180 * dx;
updateGL();
}
what does the & operator do in the if statement?
is it exactly the same as == ?

It is not the same as ==. It is bitwise AND operator. What the expression does is that it takes the return value from event->buttons() and bitwise AND's it with the value represented by Qt::LeftButton. If the resulting value is non-zero the block is being executed.
In essence, it checks if the button specified by Qt::LeftButton is held down.
The reason why the bitwise AND operator is used here is something called a bitmask. What it means is that the return value of event->buttons() is just a value which has it's bits represent different kinds of states. What is done with the &-operator here is that it checks if certain bits(denoted by Qt::LeftButton) are being set(1) or unset(0) in the value returned by event->buttons(). The return value is zero if no tested bit is set, and non-zero, if at least one of the tested bits is set.
More details of how bitwise operations work can be found here: Wikipedia article about Bitwise operations

That will test that the value event=>buttons() has the bit Qt::LeftButton.
The result would be a 0, if it did not have that bit. and a Qt::LeftButton if it did include that bit.
it is a comparison to check the existence of a flag or bit value on a number
0001 == 1
0010 == 2
0011 == 3
1 & 2 == 0 (false)
1 & 3 == 1 (true)
2 & 3 == 2 (true)
essentially it is a match across the two values for their bit values.
(0001)
& (0010)
---------
(0000) //Neither have the same bit
(0011)
& (0010)
---------
(0010) //both have bit 2
(0101)
& (0110)
---------
(0100) // Both have the 3rd bit
(0111)
& (0110)
---------
(0110) // Both have the 2nd and 3rd bit
Boolean values in C languages are 0 for false. and anything non zero is true.
This proved that the 1st and 2nd bit are available in the number 3. however 1 and 2 do not have matching bits.
Look into bitwise operators. to get a better understanding.
http://en.wikipedia.org/wiki/Bitwise_operation

It's the bitwise AND operator.
0011
& 0101
------
0001

event->buttons() presumably returns a value that's a combination of bits where each bit represents one button. Qt::LeftButton is going to be a value that probably has just a single bit set in the position that corresponds to the "left button". Using bitwise AND (&) here ANDs the individual bits of those two values, and the condition will be considered true if the result is non-zero.
Since there's only one bit in Qt::LeftButton, the only way to get a non-zero value is if event->buttons() has the same bit set. (It may have other bits set too, but those go away when they're ANDed with the zero bits in those positions in Qt::LeftButton. Effectively, then, the expression means "true if and only if event->buttons() includes the bit represented by Qt::LeftButton".

This is the bitwise AND operator. The better question is: What's the job of the AND operator here? Why are we using such a "low-level" method here?
We got a set of flags here. The set of buttons held down is represented by event->buttons(). That means, it is the sum of all buttons held down. But every button is a unique power of two, so the sum of all buttons held down is a set of bits in an integer. I hope you understand this, as this is an essential part of how we can represent simple sets of limited elements in C / C++.
The point is, every bit in the so-called bitset represents one element in the set. So does every element have a unique number, which we have to be able to test against the bitset (if it is contained in the bitset).
If you want to test whether or not the left button was held down during the event, you have to check whether or not the bit is set in the bitset. This is done using the bitwise AND operator, as this combines all the bits of the operands bit for bit using the boolean AND operation. As you should know, the AND oepration returns true if and only if both of the input bits are true. So the bitwise AND operation works as a mask for the input bits. The right operand "filters out" the bits of the left operand which are present in the right operand.
As the if condition is interpreted as true if and only if the value is unequal zero, this equals the question whether or not the bits of the right operand also appear in the left operand. In this concrete scenario, this means: Is the value Qt::LeftButton bitwise contained in the value event->buttons(), or: is the bit represented by Qt::LeftButton contained in the bitset represented by event->button()?
Or simply: Is the left button held down?

Related

Why does this two's complement shortcut work?

A shortcut method of forming the two's complement of a binary number is to copy bits from the right until a one-bit has been copied, then complement (invert) the remaining bits.
That's explained on SO here and also on Wikipedia.
What is not explained is why this shortcut works, that is, why does it produce the same result as inverting all the bits and adding one. So, my question is, why does this work?
It works because adding one to a binary number is accomplished by flipping all 1s to 0s from the right until a 0 is reached, flip that to 1 and stop (essentially carrying the overflow of adding 1 to 1).
So one method flips only the bits to the left of the first one, while the other flips all bits, then flips the first 1 (now 0) and the bits to the right of it back.
e.g.:
01000100
10111100 // copy bits until a 1 is reached, then flip the rest
vs
01000100
10111011 // invert all bits:
+ 1 // add one
10111100
Write the number as x10k (some string of bits followed by a 1 and then k zeroes).
Suppose you complement it and then add one, you'd get first y01k (where y is the complement of x), then the increment carries through the trailing ones and flips the zero back on, to y10k.
Which is the same thing as just complementing x and leaving the tail alone.
So I've found a shortcut;
Note:This trick works if you are allowed to use a calculator with binary to decimal conversion available.
If there was an MCQ question like;
Q)The 8bit 2's complement representation of 5 is ....
,Use the formula = 2^(number of bits) - the number
In this case its 8 bits and the number 5
So; (2^8) - 5
2^8=256
256-5= 251
Convert 251 into binary using calculator
Then = 11111011 in binary.
Works with any number with respect to number of bits.

query on bitwise ANDing after bitwise ORing

I came across a code snippet where AND-ing a value with all 1's is made after OR-ing the value with a number. For example:
value|=0x100;
value &=0xFFFF;
Why is the AND-ing required? I believe no matter if we do the AND-ing or not, the value in status remains same after OR-ing. But trying to understand the intention of AND-ing with all 1's again.
The ANDing is probably copy pasted from some other code where it made a difference. The intention is to keep the result to 16 bits, its like an assembler programmers typecast to 16 bits. Very useful if the result of the operation becomes negative.

Count the bits set in 1 for binary number in C++

How many bits are set in the number 1 in one binary number of 15 digits.
I have no idea how to start this one. Any help/hints?
Smells like homework, so I'll be all vague and cryptic. But helpful, since that's what we do here at SO.
First, let's figure out how to check the first bit. Hint: you want to set all other bits of the variable to zero, and check the value of the result. Since all other bits are zero, the value of the variable will be the value of the first bit (zero or one). More hint: to set bits to zero, use the AND operation.
Second, let's move the second bit to the first position. There's an operation in C++ just for that.
Third, rinse and repeat until done. Count them ones as you do so.
EDIT: so in pseudocode, assuming x is the source variable
CountOfOnes=0
while X != 0
Y = the first bit of X (Y becomes either 0 or 1)
CountOfOnes = CountOfOnes + Y
X = X right shift 1
Specifically for C++ implementation, you need to make X an unsigned variable; otherwise, the shift right operation will act up on you.
Oh, and << and >> operators are exactly bitwise shift. In C++, they're sometimes overridden in classes to mean something else (like I/O), but when acting on integers, they perform bit shifting.

Can this C/C++ if() statement ever evaluate to TRUE?

According to PC-lint, the following statement will never be TRUE:
if((variable & 0x02) == 1)
I am using a C compiler for embedded systems that evaluates it to TRUE whenever the corresponding bit in variable is set. I guess the compiler is doing a TRUE/FALSE comparison of both sides of the == instead of comparing the resulting numbers. In other words, every time the expression (varable & 0x02) is not zero (i.e. TRUE), the statement will also be TRUE, since the value 1 is also TRUE (not zero).
I don't know if the C/C++ standards clearly define how a compiler should behave in this case. Are there any C/C++ experts out there who can answer this question based on what the standards (e.g. C90, C99, etc.) say?
P.S.: In the statement above, "variable" is an unsigned char.
PC-lint is right. Assuming var is an integer variable, the expression var & 0x02 can evaluate to two values: 0 and 2. It will never be equal to 1, which is what the if statement is testing.
To expand on this, the equality operator is being applied to two integer values. What matters is whether both operands evaluate to the same number, not whether they're both simultaneously "true" or "false".
To test whether bit 1 is set, one could use:
if (variable & 0x02) {
...
}
Given that your compiler behaves the way you say it does, it's clearly non-compliant. However, it will almost certainly handle if (variable & 0x02) correctly. My recommendation would be to fix the code so it won't break silently if you were ever to change compilers.
Finally, the situation is different if: (1) the code is C++ and not C; and (2) variable is instance of a class; and (3) the class overloads the operators in question. In that case, the behaviour is down to what the overloaded operators actually do.
In C++, this can evaluate to a true value if (and only if) variable is an instance of a class with an overloaded operator& which does not conform to normal bitwise AND semantics.
In C, this condition will always be false. ยง6.5.10 defines the semantics of the bitwise AND operator, and it's quite simple and to the point:
4. The result of the binary & operator is the bitwise AND of the operands (that is, each bit in
the result is set if and only if each of the corresponding bits in the converted operands is
set).
It's clear that the result cannot be 1, as the 1 bit is not set in the converted value of the right-hand-side operand (namely, 0x02).
Naturally, if undefined behavior has been invoked at some point in the program's past (or at compile time!), then anything can happen. Barring this possibility, however, your compiler is non-compliant. That is to say, broken. This, unfortunately, is extremely common on odd embedded compilers. If you're lucky, you may even be able to report the bug and get it fixed.
I don't think the standard defines anything about this very specific and unusual issue. As said by aix, that statement can never be true because (in binary):
XXXX XXXX -> variable
0000 0010 -> 0x02
--------- AND
0000 00X0 -> result
(simplifying to 8-bit types)
So your only results can be 0000 0010 (which is 2) or 0000 0000 (which is 0).
For C, the answer is no.
The C standard says about & (6.5.10):
The result of the binary & operator is the bitwise AND of the operands (that is, each bit in
the result is set if and only if each of the corresponding bits in the converted operands is
set).
Since in 2 only the bit 1 is set, the value of the expression can only have set the bit 1. It can take no other values than 2 and 0. Neither 2 nor 0 can compare equal to 1.
The bit representations of integers are defined in 6.2.6.2 (for non-negative values in the usual way).
Basically, lint is right here. At least on any platform I know of, the condition will yield false. Look at the bit representation of the numbers: x & 2 (0010) will always be either zero or 2 (0010) and thus different from 1 (0001) for any integer x.
Let us consider the binary value of 2
02 = 0010 (say a 4 bit number)
and the binary value of 1 is
01 = 0001
The least significat bit of 2 is always zero that is the left most bit is 0. SO
The & (and) operation with 0 never gives 1 hence we can say it can never be equal to 1
0 0 => 0
0 1 => 0
1 1 => 1
Note: & indicates the bit wise and operation
2 - 0010
3 - 0011
0010
So the output with xx & 2 will be 0 or 2.

How can I set all bits to '1' in a binary number of an unknown size?

I'm trying to write a function in assembly (but lets assume language agnostic for the question).
How can I use bitwise operators to set all bits of a passed in number to 1?
I know that I can use the bitwise "or" with a mask with the bits I wish to set, but I don't know how to construct a mask based off some a binary number of N size.
~(x & 0)
x & 0 will always result in 0, and ~ will flip all the bits to 1s.
Set it to 0, then flip all the bits to 1 with a bitwise-NOT.
You're going to find that in assembly language you have to know the size of a "passed in number". And in assembly language it really matters which machine the assembly language is for.
Given that information, you might be asking either
How do I set an integer register to all 1 bits?
or
How do I fill a region in memory with all 1 bits?
To fill a register with all 1 bits, on most machines the efficient way takes two instructions:
Clear the register, using either a special-purpose clear instruction, or load immediate 0, or xor the register with itself.
Take the bitwise complement of the register.
Filling memory with 1 bits then requires 1 or more store instructions...
You'll find a lot more bit-twiddling tips and tricks in Hank Warren's wonderful book Hacker's Delight.
Set it to -1. This is usually represented by all bits being 1.
Set x to 1
While x < number
x = x * 2
Answer = number or x - 1.
The code assumes your input is called "number". It should work fine for positive values. Note for negative values which are twos complement the operation attempt makes no sense as the high bit will always be one.
Use T(~T(0)).
Where T is the typename (if we are talking about C++.)
This prevents the unwanted promotion to int if the type is smaller than int.