I've been struggling for a while with a part of my code and I finally found that the problem lies with a simple test that don't give me the result I expect.
if (2) //=> true
if (2 & true) //=> false
if (bool(2) & true) //=> true
What I don't understand is why the second line results in false.
My understanding was that every non-zero integer was considered as true in a test.
Because the bitwise and between 2 and true is false.
& (bitwise operator) is different than && (logical operator).
true cast to int is 1.
So 2 & true is 2 & 1 which is false - because 0000000000000010 & 0000000000000001 == 0. (bits may vary)
Whereas bool(2) == 1, and 1 & 1 is true.
if (2) //=> true
So far, so good.
if (2 & true) //=> false
The condition here evaluates to 2 & 1 == 0, because & is a bitwise operator and 2 and 1 are respectively 00000010 and 00000001 in binary.
if (bool(2) & true) //=> true
Interestingly enough, on my compiler I seem to recall erratic behavior in some cases like this; and, if sect. 4.12 of the C++11 standard addresses the matter, it does so in a manner I do not understand. I seem to recall seeing my compiler let bool(2) == 2, which one would not expect. Whether this represents a bug in my compiler or a fault in my recollection, I do not know.
I suspect however that you want the logical operator && rather than the bitwise operator &.
QUIZ
To check your understanding, try
if (3 & true) //=> true
Do you understand why? (Hint: the binary representation of 3 is 00000011.)
You need && instead of &.
&& is the boolean and operator, whereas & is the binary 'and' so 2 & true is the same as 0010 & 0001 = 0000 -> false whereas 2 && true = true.
& does an AND between all the bits (call bitwise AND) , what you need is the && operator (boolean AND).
2 in binary is '10' and true is 1 (01) in binary, the result 10 & 01 is therefore 0 .
bool(2) convert 2 to true , is 01 in binary, and 01 & 01 is 01.
Related
I came across a part of code that I cannot understand.
for (unsigned int i = (x & 0b1); i < x; i+= 2)
{
// body
}
Here, x is from 0 to 5.
What is meant by 0b1? and what would be the answers for eg: (0 & 0b1), (4 & 0b1) etc?
0b... is a binary number, just like 0x... is hex and 0... is octal.
Thus 0b1 is same as 1.
1b0 is illegal, the first digit in those must always be 0.
As previous answers said, it is the binary representation of the integer number 1, but they don't seem to have fully answered your question. This has a lot of layers so I'll briefly explain each.
In this context, the ampersand is working as a bitwise AND operator. i & 0b1 is (sometimes) a faster way of checking if an integer is even as opposed to i % 2 == 0.
Say you have int x = 5 and you'd like to check if it's even using bitwise AND.
In binary, 5 would be represented as 0101. That final 1 actually represents the number 1, and in binary integers it's only present in odd numbers. Let's apply the bitwise AND operator to 5 and 1;
0101
0001
&----
0001
The operator is checking each column, and if both rows are 1, that column of the result will be 1 – otherwise, it will be 0. So, the result (converted back to base10) is 1. Now let's try with an even number. 4 = 0100.
0100
0001
&----
0000
The result is now equal to 0. These rules apply to every single integer no matter its size.
The higher-level layer here is that in C, there is no boolean datatype, so booleans are represented as integers of either 0 (false) or any other value (true). This allows for some tricky shorthand, so the conditional if(x & 0b1) will only run if x is odd, because odd & 0b1 will always equal 1 (true), but even & 0b1 will always equal 0 (false).
I have a problem relative to some C++ code about the !! operator. It gives me an unexpected result and I don't understand why:
int x=-12;
x=!!x;
print("value=",x);
The output of this is 1. But i do not know how. Can anyone explain this ambiguous result?
!!x is grouped as !(!x).
!x is 0 if x is non-zero, and 1 if x is zero.
Applying ! to that reverses the result.
So, !!x can be viewed as a way of setting x to 1 if it's not zero, and remaining at 0 if it's zero. In other words x = !!x is the same as x = x ? 1 : 0.
... !(-12) kindly explain this expression.
It's "logical not of -12". In C++ numeric value 0 is false in logical way, and any non-zero value is true in logical way. This is how C and C++ evaluates numerical values in boolean context, like if (expression) ..., i.e. if (-12) exit(1); will exit your application, because -12 is "true".
When you typecast numeric value to bool type and then back to int, the true will become value 1, but most of the time you can avoid these conversions and use intermediate results of numerical calculations directly, where any non-zero value is "true".
So "not of true" is value false. I.e. !(-12) == false. And !false == true. And you convert the logical value "true" back to int, which will make x == 1.
The !!(numeric_value) is idiomatic way in C++ (and in C too) to "normalize" any numeric value into precisely 0 or 1 (and you may encounter it in source code of many applications).
The "logical" distinction is important, because C++ has also binary operators, where the calculation is working per individual bits, not with value as whole. In "binary" way the "!" operator sibling is ~. Similar example to yours with bit-complement operator x=~~x; would then result into original value -12, because every bit of x is flipped twice, ending with same value as it did start. So ~~x is not something to encounter in regular source, as it's basically "no operation" (contrary to !! which is "no operation" only if the original value was already 0 or 1).
Also this is sometimes source of bugs for people learning the language, as they forget about the distinction and write something like
if (4 & 2) { /* this is "and" so it should be true??? */ }
// it will be false, because in binary way 4&2 == 0
if (4 && 2) { /* this is logical "and" and will be "true" */ }
// because 4 is non-zero, 2 is non-zero, and "true and true" is "true"
I.e. binary operators are & | ~ ^ (and, or, not, xor), and their logical siblings are && || ! for "and, or, not", the logical "xor" doesn't have operator in C++.
This question already has answers here:
Can I use bitwise operators instead of logical ones?
(5 answers)
Closed 6 years ago.
1st Semester Student here. I'm confused about the differences between the bitand (&) and the logical and (&&), and the same with the bitor (|), the logical or (||), and the Xor (^). Specifically, I've a bit of code that I thought required the || or && to function, but.. apparently not? Here's the code in question:
cout << "Please enter your biological sex (M or F): " << endl;
cin >> sex;
//Repetition Structure
while (toupper(sex) != 'M' && 'F')
{
cout << "Invalid entry. Please enter your biological sex (M or F): " << endl;
cin >> sex;
} //end while
I tried using || at first, but it gave me the "invalid entry" reply no matter how I answered it. I looked around on the forums, found that && would be better and tried using it. It worked - at first. Then, for no apparent reason, it stopped taking 'F' as an answer (the code wasn't changed).
To correct this, I tried using Xor (^) which failed, and then bitand (&, instead of &&), which apparently made it function correctly once more. But, I've seen warnings that you can still get the right answers using either & or &&, but one does not equal the other and could cause problems later. This is why I need clarification (also, it's just good stuff to know).
UPDATE: Since this was tagged as a duplicate, I'll clarify my intent: I want to know more about & and &&, why you use one and not the other, as well as the same info for ^, | and ||. The tagged thread has examples of using one versus another, but they don't explain the details of the operations themselves. As I'm struggling with understanding the very nature of the operations themselves, those explanations are crucial; examples alone won't clarify my understanding.
This isn't something you use bit operators for. You want to compare input string with a desired 'M' or 'F' so all you have to do is:
while (toupper(sex) != 'M' && toupper(sex) != 'F') {...
In your code you were missing the second toupper(sex) != part. You need to look at this statement as two requirements that have to be met in order for while to continue.
First one is: toupper(sex) != 'M'
Second on: toupper(sex) != 'F'
The reason why a &&(logical and) should be between those two is because you want the while loop to run if sex isn't M and at the same time it isn't F.
Operators like & and | are for comparing bits of a variable. For example if you want to use bit flags you set each of your flag to one bit and compare the resulting flag combination with &.
EDIT: So for bit flags, they compare the value you give them bit by bit. So what you do for bit flags is you can define them as powers of 2 (1, 2, 4, 8...) which each represents on position in binary (00000001, 00000010, 00000100, 00001000 ...). So for example when you have flags:
a = 1;
b = 2;
c = 4;
You can set them with ``| to your set of flags:
setFlags = setFlags | a | c;
This will compare the setFlags bit by bit with a and c.
00000000
|00000001 // a
|00000100 // c
=00000101 // result
So the | operator checks all the bits of the same position and if one of them is true, the result will be true just like logical OR.
Now to read them you use & like this:
if (setFlags & a)
which does:
00000101 // setFlags
&00000001 // a
=00000001 // result
this leaves only bits where they both are true (just like logical AND), therefore you can get true if the setFlags contains that flag.
00000101 // setFlags
&00000010 // b
=00000000 // result
in this case there are no bits set to true on same position so the result tells you that b isn't set in setFlags.
while (toupper(sex) != 'M' && 'F') is evaluated as:
while(true && (bool)'F'): while(true && true) // or
while(false && (bool)'F'): while(false && true)
because if you sex is assigned 'm' or 'M' then the condition is true and you used logical and && on a non-zero value 'f' the result is always true.
it is like: if( (bool)5 ) which is true because the bool values of any non-zero value is always true.
to correct you example:
while (toupper(sex) != 'M' && toupper(sex) != 'F')
logical operators like logical and &&, logical or ||,... return bool values true or false; 1 or 0 they evaluate expressions.
bitwise operators like bitwise and &, bitwise or |... return any value, the y work on bits:
unsigned char uc1 = 13; // 0x01 00001101
unsigned char uc2 = 11; // 0x03 00001011
unsigned char uc3 = (uc1 & uc2);// 00001001
as you can see 1 & 1 = 1, 0 & 1 = 0, 1 & 0 = 0, 1 & 1 = 1, 0 & 0 = 0...
the result us 00001001 which is in decimal 9
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 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 ~.