I heard that often "everything" besides 0 is true. But now very strange things are happening to me... or I just think that I do it in correct way while I don't. Here's what is happening:
When I want to check if a is equivalent b, I can use NOT(a XOR b)
. When I checked it for unsigned char
's, everything was ok, for example
unsigned char a = 5;
unsigned char b = 3;
unsigned char c = ~(a^b);
gave me c == 249
:
a is: 00000101
, which is 5.
b is: 00000011
, which is 3.
~(a^b) is: 11111001
, which is 249.
Now, let's try this with bool
's.
cout << ~(true^true) << ~(true^false) << ~(false^true) << ~(false^false) << endl;
cout << ~(~(true^true)) << ~(~(true^false)) << ~(~(false^true)) << ~(~(false^false)) << endl;
if (~(true^true) == true)
cout << "true";
else
cout << "false";
This gives me in console:
-1-2-2-1
0110
false
while I expected the first line to be:
1001
After asking a friend, he advised me to try !
instead of ~
and see if it will work correctly. And (I think) it works correctly now. But I don't understand why. Shouldn't boolean negation work for bools?
The ! (logical negation) operator determines whether the operand evaluates to 0 (false) or nonzero (true). The expression yields the value 1 (true) if the operand evaluates to 0, and yields the value 0 (false) if the operand evaluates to a nonzero value.
Zero is used to represent false, and One is used to represent true. For interpretation, Zero is interpreted as false and anything non-zero is interpreted as true. To make life easier, C Programmers typically define the terms "true" and "false" to have values 1 and 0 respectively.
The logical NOT ( ! ) operator (logical complement, negation) takes truth to falsity and vice versa. It is typically used with boolean (logical) values. When used with non-Boolean values, it returns false if its single operand can be converted to true ; otherwise, returns true .
Like in C, the integers 0 (false) and 1 (true—in fact any nonzero integer) are used.
You're misunderestimating the arithmetic conversions. When you say ~e
for some expression e
of integral type, the value is first promoted to at-least-int
, and same for e1 ^ e2
(and for any arithmetic expressions, for that matter). So true ^ true
first has its operands promoted to int
, yielding 1 ^ 1
, which is indeed 0, and thus you end up with ~0
, which on your platform is -1
.
You can vaguely make sense of your operation by converting the result back to bool
:
std::cout << static_cast<bool>(~(true ^ true))
In your final problem, since you have an expression with the ==
operator where the two operands have different types, both operands are promoted to the common type, which is again int
, and -1
is different from 1
. Again, you can convert both operands to bool
first to get the desired equality.
The meta lesson is that the built-in operators in C++ acting on integers really only operate on int
and wider, but not on any of the shorter types (bool
, char
, short
) (and similar considerations apply to passing integers through an ellipsis). While this may cause some confusion at times, it also simplifies the language rules a bit, I suppose. This is all part of the C heritage of C++.
I heard that often "everything" besides 0 is true
It is valid for conditions as for example in the if statement (here and below I am citing the C++Standard)
The value of a condition that is an expression is the value of the expression, contextually converted to bool for statements other than switch
For example if you would write as
if (~(true^true) )
cout << "true";
else
cout << "false";
instead of your code snippet
if (~(true^true) == true)
cout << "true";
else
cout << "false";
or when the logical negation operator !
is used
9 The operand of the logical negation operator ! is contextually converted to bool (Clause 4); its value is true if the converted operand is false and false otherwise. The type of the result is bool
As for operator ==
then
6 If both operands are of arithmetic or enumeration type, the usual arithmetic conversions are performed on both operands; each of the operators shall yield true if the specified relationship is true and false if it is false.
That is in case of
if (~(true^true) == true)
the usual arithmetic conversion is applied that is boolean value true is converted to integer value 1 and it is not equal to the expression of the left operanf because internal binary representation of the left operand differs from 1 as showed the output of your first code snippet..
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With