Related
This question already has answers here:
Why can't we use bitwise operators on float & double data types
(2 answers)
Closed 7 years ago.
These are two simple samples in C++ written on Dev-cpp C++ 5.4.2:
float a, b, c;
if (a | b & a | c)
printf("x = %.2f\tF = %.0f\n", x, F);
else
printf("x = %.2f\tF = %.2f\n", x, F);
and this code :
float a, b, c;
if (a || b && a || c)
printf("x = %.2f\tF = %.0f\n", x, F);
else
printf("x = %.2f\tF = %.2f\n", x, F);
Can somebody tell my difference between || > | and & > &&. The second code works , but first does not.
And compiler gives an error message :
[Error] invalid operands of types 'float' and 'float' to binary 'operator&'.
The operators |, &, and ~ act on individual bits in parallel. They can be used only on integer types. a | b does an independent OR operation of each bit of a with the corresponding bit of b to generate that bit of the result.
The operators ||, &&, and ! act on each entire operand as a single true/false value. Any data type can be used that implicitly converts to bool. Many data types, including float implicitly convert to bool with an implied !=0 operation.
|| and && also "short circuit". That means whenever the value of the result can be determined by just the first operand, the second is not evaluated. Example:
ptr && (*ptr==7) If ptr is zero, the result is false without any risk of seg faulting by dereferencing zero.
You could contrast that with (int)ptr & (*ptr). Ignoring the fact that this would be a bizarre operation to even want, if (int)ptr were zero, the entire result would be zero, so a human might think you don't need the second operand in that case. But the program will likely compute both anyway.
You seems be confused with the symbols of the operators. Theses symbols are actually split in two different categories, which are bit-wise operators and logical operators. Although they use the same symbols, you should regard them as different operators. The truth tables for both categories are similar, but the meanings are different. Maybe that's why people use the similar symbols for the operators.
bit-wise operators
~ // NOT
& // AND
| // OR
^ // XOR
The bit-wise operators will regard all its operands as binary numerals and act according to the bit-wise truth tables on every bit of the operands.
Bit-wise Truth Table
x y x&y x|y x^y
0 0 0 0 0
1 0 0 1 1
0 1 0 1 1
1 1 1 1 0
x ~x
0 1
1 0
logical operators
! // Logical NOT (negation)
&& // Logical AND (conjunction)
|| // Logical OR (disjunction)
The logical operator will regard all its operands as bools and act according the operator truth tables. Any number that is not equal to 0 will be true, else will be false.
Logical Truth Table
x y x&&y x||y
F F F F
T F F T
F T F T
T T T T
x !x
F T
T F
For example:
int a = 10; // a = 0000 .... 0000 1010 <-- a 32 bits integer
// a is not zero -> true
int b = 7; // b = 0000 .... 0000 0111 <-- a 32 bits integer
// b is not zero -> true
Then for bit-wise operator:
assert(a & b == 2); // 2 = 0000 .... 0000 0010 <-- every bit will & separately
For logic operator:
assert(a && b == true); // true && true -> true
The bitwise operators, which are | (OR), & (AND), ^ (XOR), and ~ (complement) do what you expect them to do: they perform the aforementioned operations on bits.
And regarding your compilation issue, there are no bitwise operations for floating point numbers.
The logical operators, which are || (OR), && (AND), and ! (NOT) only know the values true and false.
An expression is true if its value is not 0. It is false if its value equals 0.
The logical operators do this operation first. Then they perform their corresponding operation:
||: true if at least one the operands is true
&&: true if both operands are true
!: true if the operand is false
Note that all logical operators are short-circuit operators.
Bitwise operation is not supported for floating points
Alternatively if you really need to check, you can cast before you use them (highly discouraged),
Check here how to convert a float into integrals, https://www.cs.tut.fi/~jkorpela/round.html
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.
#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.
I have written this C++ program, and I am not able to understand why it is printing 1 in the third cout statement.
#include<iostream>
using namespace std;
int main()
{
bool b = false;
cout << b << "\n"; // Print 0
b = ~b;
cout << b << "\n"; // Print 1
b = ~b;
cout << b << "\n"; // Print 1 **Why?**
return 0;
}
Output:
0
1
1
Why is it not printing the following?
0
1
0
This is due to C legacy operator mechanization (also recalling that ~ is bitwise complement). Integral operands to ~ are promoted to int before doing the operation, then converted back to bool. So effectively what you're getting is (using unsigned 32 bit representation) false -> 0 -> 0xFFFFFFFF -> true. Then true -> 1 -> 0xFFFFFFFE -> 1 -> true.
You're looking for the ! operator to invert a boolean value.
You probably want to do this:
b = !b;
which is logical negation. What you did is bitwise negation of a bool cast to an integer. The second time the statement b = ~b; is executed, the prior value of b is true. Cast to an integer this gives 1 whose bitwise complement is -2 and hence cast back to bool true. Therefore, true values of b will remain true while false values will be assigned true. This is due to the C legacy.
As pretty much everyone else has said, the bool is getting promoted to an integer before the complement operator is getting its work done. ~ is a bitwise operator and thus inverts each individual bit of the integer; if you apply ~ to 00000001, the result is 11111110. When you apply this to a 32-bit signed integer, ~1 gives you -2. If you're confused why, just take a look at a binary converter. For example: http://www.binaryconvert.com/result_signed_int.html?decimal=045050
To your revised question:
False to true works for the same reason as above. If you flip 00000000 (out to 32 bits), you get 11111111... which I believe is -1 in integer. When comparing boolean values, anything that is -not- 0 is considered to be true, while 0 alone is false.
You should use logical operators, not binary operators. Use ! instead of ~.
I am trying to learn C programming, and I was studying some source codes and there are some things I didn't understand, especially regarding Bitwise Operators. I read some sites on this, and I kinda got an idea on what they do, but when I went back to look at this codes, I could not understand why and how where they used.
My first question is not related to bitwise operators but rather some ascii magic:
Can somebody explain to me how the following code works?
char a = 3;
int x = a - '0';
I understand this is done to convert a char into an int, however I don't understand the logic behind it. Why/How does it work?
Now, Regarding Bitwise operators, I feel really lost here.
What does this code do?
if (~pointer->intX & (1 << i)) { c++; n = i; }
I read somewhere that ~ inverts bits, but I fail to see what this statement is doing and why is it doing that.
Same with this line:
row.data = ~(1 << i);
Other question:
if (x != a)
{
ret |= ROW;
}
What exactly is the |= operator doing? From what I read, |= is OR but i don't quite understand what is this statement doing.
Is there any way of rewriting this code to make it easier to understands so that it doesn't use this bitwise operators? I find them very confusing to understand, so hopefully somebody will point me in the right direction on understanding how they work better!
I have a much better understanding of bitwise operators now and the whole code makes much more sense now.
One last thing: appartenly nobody responded if there would be a "cleaner" way for rewriting this code in a way that its easier to understand and maybe not at "bitlevel". Any ideas?
This will produce junk:
char a = 3;
int x = a - '0';
This is different - note the quotes:
char a = '3';
int x = a - '0';
The char datatype stores a number that identifiers a character. The characters for the digits 0 through 9 are all next to each other in the character code list, so if you subtract the code for '0' from the code for '9', you get the answer 9. So this will turn a digit character code into the integer value of the digit.
(~pointer->intX & (1 << i))
That will be interpreted by the if statement as true if it's non-zero. There are three different bitwise operators being used.
The ~ operator flips all the bits in the number, so if pointer->intX was 01101010, then ~pointer->intX will be 10010101. (Note that throughout, I'm illustrating the contents of a byte. If it was a 32-bit integer, I'd have to write 32 digits of 1s and 0s).
The & operator combines two numbers into one number, by dealing with each bit separately. The resulting bit is only 1 if both the input bits are 1. So if the left side is 00101001 and the right side is 00001011, the result will be 00001001.
Finally, << means left shift. If you start with 00000001 and left shift it by three places, you'll have 00001000. So the expression (1 << i) produces a value where bit i is switched on, and the others are all switch off.
Putting it all together, it tests if bit i is switched off (zero) in pointer->intX.
So you may be able to figure out what ~(1 << i) does. If i is 4, the thing in brackets will be 00010000, and so the whole thing will be 11101111.
ret |= ROW;
That one is equivalent to:
ret = ret | ROW;
The | operator is like & except that the resulting bit is 1 if either of the input bits is 1. So if ret is 00100000 and ROW is 00000010, the result will be 00100010.
ret |= ROW;
is equivalent to
ret = ret | ROW;
For char a = 3; int x = a - '0'; I think you meant char a = '3'; int x = a - '0';. It's easy enough to understand if you realize that in ASCII the numbers come in order, like '0', '1', '2', ... So if '0' is 48 and '1' is 49, then '1' - '0' is 1.
For bitwise operations, they are hard to grasp until you start looking at bits. When you view these operations on binary numbers then you can see exactly how they work...
010 & 111 = 010
010 | 111 = 111
010 ^ 111 = 101
~010 = 101
I think you probably have a typo, and meant:
char a = '3';
The reason this works is that all the numbers come in order, and '0' is the first. Obviously, '0' - '0' = 0. '1' - '0' = 1, since the character value for '1' is one greater than the character value for '0'. Etc.
1) A char is really just a 8-bit integer. '0' == 48, and all that that implies.
2) (~(pointer->intX) & (1 << i)) evalutates whether the 'i'th bit (from the right) in the intX member of whatever pointer points to is not set. The ~ inverts the bits, so all the 0s become 1s and vice versa, then the 1 << i puts a single 1 in the desired location, & combines the two values so that only the desired bit is kept, and the whole thing evalutes to true if that bit was 0 to begin with.
3) | is bitwise or. It takes each bit in both operands and performs a logical OR, producing a result where each bit is set if either operand had that bit set. 0b11000000 | 0b00000011 == 0b11000011. |= is an assignment operator, in the same way that a+=b means a=a+b, a|=b means a=a|b.
Not using bitwise operators CAN make things easier to read in some cases, but it will usually also make your code significantly slower without strong compiler optimization.
The subtraction trick you reference works because ASCII numbers are arranged in ascending order, starting with zero. So if ASCII '0' is a value of 48 (and it is), then '1' is a value of 49, '2' is 50, etc. Therefore ASCII('1') - ASCII('0') = 49 - 48 = 1.
As far as bitwise operators go, they allow you to perform bit-level operations on variables.
Let's break down your example:
(1 << i) -- this is left-shifting the constant 1 by i bits. So if i=0, the result is decimal 1. If i = 1, it shifts the bit one to the left, backfilling with zeros, yielding binary 0010, or decimal 2. If i = 2, you shift the bit two to the left, backfilling with zeros, yielding binary 0100 or decimal 4, etc.
~pointer->intX -- this is taking the value of the intX member of pointer and inverting its bits, setting all zeros to ones and vice versa.
& -- the ampersand operator does a bitwise AND comparison. The results of this will be 1 wherever both the left and right side of the expression are 1, and 0 otherwise.
So the test will succeed if pointer->intX has a 0 bit at the ith position from the right.
Also, |= means to do a bitwise OR comparison and assign the result to the left side of the expression. The result of a bitwise OR is 1 for every bit where the corresponding left or right side bit is 1,
Single quotes are used to indicate that a single char is used. '0' therefore is the char '0', which has the ASCII-Code 48.
3-'0'=3-48
'1<<i' shifts 1 i places to the left, therefore only the ith bit from the right is 1.
~pointer->intX negates the field intX, so the logical AND returns a true value (not 0) when intX has every bit except for the ith bit from the right isn't set.
char a = '3';
int x = a - '0';
you had a typo here (notice the 's around the 3), this assigns the ascii value of the character 3, to the char variable, then the next line takes '3' - '0' and assigns it to x, because of the way ascii values work, x will then be equal to 3 (integer value)
In the first comparison, I've never seen ~ being used on a pointer that way before, another typo maybe? If I were to read out the following code:
(~pointer->intX & (1 << i))
I would say "(the value intX dereferenced from pointer) AND (1 left shifted i times)"
1 << i is a quick way of multiplying 1 by a power of 2, ie if i is 3, then 1 << 3 == 8
In this case, I have no clue why you would invert the bits of the pointer..
In the 2nd comparison, x |= y is the same as x = x | y
I'm assuming you mean char a='3'; for the first line of code (otherwise you get a rather strange answer). The basic principal is that ASCII codes for digits are sequential, i.e. the code for '0'=48, the code for '1'=49, and so on. Subtracting '0' simply converts from the ASCII code to the actual digit, so e.g. '3' - '0' = 3, and so on. Note that this will only work if the character you're subtracting '0' from is an actual digit - otherwise the result will have little meaning.
a. Without context the "why" of this code is impossible to say. As for what it's doing, it appears that the if statement evaluates as true when bit i of pointer->intX is not set, i.e. that particular bit is a 0. I believe the & operator gets executed before the ~ operator, as the ~ operator has very low precedence. The code could make better use of parentheses to make the intended order of operations clearer. In this case, the order of operations might not matter though - I believe the result is the same either way.
b. This is simply creating a number with all bits EXCEPT bit i set to 1. A convenient way of creating a mask for bit i is to use the expression (1<<i).
The bitwise OR operation in this case is used to set the bits specified by the ROW constant to 1. If these bits are not set, it sets them; if they're already set it has no effect.
1) Can somebody explain to me how the following code works? char a = 3; int x = a - '0';
I undertand this is done to convert a char into an int, however I don't understand the logic behind it. Why/How does it work?
Sure. variable a is of type char, and by putting single quotes around 0 that is causing C to view it as a char as well. Finally, the whole statement is automagically typecast to its integer equivalent, because x is defined as an integer.
2) Now, Regarding Bitwise operators, I feel really lost here.
--- What does this code do? if (~pointer->intX & (1 << i)) { c++; n = i; } I read somewhere that ~ inverts bits, but I fail to see what this statement is doing and why is it doing that.
(~pointer->intX & (1 << i)) is saying:
negate intX, and AND it with a 1 shifted left by i bits
so, what you're getting, if intX = 1011, and i = 2, equates to
(0100 & 0100)
-negate 1011 = 0100
-(1 << 2) = 0100
0100 & 0100 = 1 :)
then, if the AND operation returns a 1 (which, in my example, it does)
{ c++; n = i; }
so, increment c by 1, and set variable n to be i
Same with this line: row.data = ~(1 << i);
Same principle here.
Shift a 1 to the left by i places, and negate.
So, if i = 2 again
(1 << 2) = 0100
~(0100) = 1011
**--- Other question:
if (x != a) { ret |= ROW; }
What exacly is the |= operator doing? From what I read, |= is OR but i don't quite understand what is this statement doing.**
if (x != a) (hopefully this is apparent to you....if variable x does not equal variable a)
ret |= ROW;
equates to
ret = ret | ROW;
which means, binary OR ret with ROW
For examples of exactly what AND and OR operations accomplish, you should have a decent understanding of binary logic.
Check wikipedia for truth tables...ie
Bitwise operations