Why is the complement operator not working when bool = true? - c++

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 ~.

Related

Operator !! producing unexpected result

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++.

Difference between | and || , or & and && [duplicate]

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

tilde operator returning -1, -2 instead of 0, 1 respectively

I'm kind of puzzled by this. I thought the ~ operator in C++ was supposed to work differently (not so Matlab-y). Here's a minimum working example:
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
bool banana = true;
bool peach = false;
cout << banana << ~banana << endl;
cout << peach << ~peach << endl;
}
And here's my output:
1-2
0-1
I hope someone will have some insight into this.
This is exactly what should happen: when you invert the binary representation of zero, you get negative one; when you invert binary representation of one, you get negative two in two's complement representation.
00000000 --> ~ --> 11111111 // This is -1
00000001 --> ~ --> 11111110 // This is -2
Note that even though you start with a bool, operator ~ causes the value to be promoted to an int by the rules of integer promotions. If you need to invert a bool to a bool, use operator ! instead of ~.
~ is bitwise NOT operator which means it flips all the bits. For boolean NOT, you should be using ! operator

printing a boolean value in c++

When I run this simple code,
int main(int argc, const char * argv[])
{
bool digit(true);
std::cout << digit << " " << ~digit << std::endl;
}
The output is
1 -2
I was expecting 1 and 0 (for true and false). Am I missing something here?
~ performs bitwise negation. The operand is promoted (in this case) to int, and all the bits are inverted. 1 has a binary representation of 00....001, so this gives the binary value 11....110, which is interpreted (on most modern computers) as -2.
Use ! for logical negation.
~ is the bitwise not (or bit inversion) operator. The logical not operator is '!'.
cout << !digit;
Essentially:
1 -> 00000001
~1 -> 11111110
You need a logical not operator is '!'.You may try this;
cout << !(digit);
EDIT:-
Although I know its late but trying to improve my answer, ~ is the bitwise not operator. So if you write something like ~1000 then it would result out to be 0001
4 bits integer
1 -> 0001
find the complement by adding 1
0001 + 0001 = 0010 = 2
the complement is -2

bitwise checking if a number is -1 or not

I have to make a function that check if a input number is -1 or not. here's the requirement
isTmin - returns 1 if x is the minimum, two's complement number, and 0 otherwise
Legal ops: ! ~ & ^ | +
Max ops: 10
Rating: 1
First I try this:
int isTmin(int x) {
return !(x^(0x01<<31));
}
this method works, but I am not allowed to use the shifting operator. any ideas how can I solve this problem w/o using shift operator?
int isTmin(unsigned x) {
return !x ^ !(x+x);
}
Note that you need to use unsigned in C to get twos-complement math and proper wrapping -- with int its implemention/undefined.
If the only thing it needs to check is if it's 0xffff ffff, then:
return x^0xffffffff == 0
This is only true if x is also 0xffffffff.