XOR and XNOR equivalent? - xor

Why are XOR and XNOR known as "non-equivalent" and "equivalent" gates ?

XOR stands for "eXclusive OR", which means, that the result is true, when AND ONLY WHEN one of the operands is true, but not when both are true or both are false. This means, when only one operand is true and the other is false, they are different meaning non-equivalent.
So XOR is only true, when one operand is true and the other is false.
NXOR stands for "Not XOR", which in short means, it is true for each case when XOR is false and vice versa.
So NXOR is only true, when either both operands are true or both operands are false, meaning when they are equivalent.

Related

Regarding logical AND operator

int a=8, b=10,c=2,d;
d= ++a && ++b || ++b;
In the above code , how do I know if (++a), (++b) are true or false . I know true is 1 and false is 0. But I can’t understand how to determine if these expressions are true or false .
Please help.
0 is false, any non-zero value is true. So you just need to determine whether ++a and ++b are zero or not zero.
Since a is initially 8, ++a is 9, which is non-zero, so it's true.
Since b is initially 10, ++b is 11, which is non-zero, so it's true.
9 && 11 is true because both the operands are true.
|| only evaluates the second operand if the first operand is false. So the second ++b ie never executed. The value of true || anything is true.
Therefore, d will be set to true, which is 1.
In C, logical operators (&&, ||, !, etc.) assume that zero is false and all other values are true.
Based on the operator precedence (operator && precedence is higher than || operator), the expression will be evaluated as:
d = (++a && ++b) || ++b;
Note that logical AND operation expr1 && expr2 employs short-circuiting behaviour. With logical short-circuiting, the second operand, expr2, is evaluated only when the result is not fully determined by the first operand, expr1.
That is, expr2 is not evaluated if expr1 is logical 0 (false).
++a will result in 9, a non zero value, hence, results in true, so right hand side operand of && operator, which is ++b, will be evaluated.
++b will result in 11, a non zero value, hence, results in true.
true && true will result in true.
Logical OR operation expr1 || expr2 employs short-circuiting behaviour. That is, expr2 is not evaluated if expr1 is logical 1 (true).
So, in the given expression, the left hand side of || is evaluated as true hence the right hand side operand of || operator, which is ++b, will not be evaluated and the result of whole expression will be true. Hence, the value of d will be 1.
In C, C++ and many other programming languages, for integers, 0 is considered false and any other integer (including negative numbers) is true. So here d will be evaluated to true
In 'C' we know that the true is '1' and false is '0' so above expression will be true because both the expressions are non zero. and if you want to print actual values like true and false i think you should try out printf("%s", x?"true":"false");

Does if (!(-1)) evaluate to true or false in C?

I know that 0 and NULL evaluate to FALSE on their own and I know that a negative integer or a positive integer evaluate to TRUE on their own.
My understanding is that the NOT operation will happen after evaluating the expression, so if (-1) will evaluate to TRUE, then applying the ! operand will mean NOT TRUE which equals FALSE. Is this the correct order of operations and is it correct that if (!(-1)) will evaluate to FALSE?
The evaluation of if (!(-1)) can be worked out by thinking about the operator precedences.
Firstly the unary - is applied to 1 which produces an integral -1. Then this value is logically negated by the !. This involves collapsing -1 into a logical value. The rule for this in C is nice and simple for integral types: 0 is falsy and everything else is truthy.
Therefore -1 is truthy and when the logical negation happens we get false.
Therefore this statement is portably false.
In standard C, any non-zero (positive/negative) value is TRUE.
So, (-1) evaluated as TRUE and, !(-1) of-course evaluated as FALSE. Hence, if (!(-1)) will evaluate to FALSE.
(-1) = 1111 1111 in binary and ! flips all bits so the byte would equal 0000 0000 which is equal to false.

C: printf not executed, possible compiler optimization?

I have the following line in my code:
1 || printf("A");
I was surprised to see that A is not printed; I am guessing this is due to compiler optimizations: 1 was evaluated as true, and, because the entire OR expression must have been true, the printf("A") wasn't even evaluated... Can someone confirm this? Would the program behave like this with different compilers?
In the expression a || b, b is only evaluated when a is false (similarly in a && b, b is only evaluated if a is true). This is known as short-circuiting and it's not an optimization, it's behavior mandated by the standard. If the compiler did anything else, it'd not be a valid implementation.
This allows you to do things like a != NULL && a->isValid() and be sure that you're not dereferencing a null pointer.
I am guessing this is due to compiler optimizations: 1 was evaluated as true, and, because the entire OR expression must have been true, the printf("A") wasn't even evaluated..
The decision to execute the printf("A") function or not is not made during compilation but it is made during execution of the program. So, this rule out your explanation of compilation optimization.
In the expression exp1 || exp2, exp1 is evaluated first. If it evaluates to true, then exp2 is not evaluated as result of logical operator is true in-spite of the value of exp2. However, if exp1 is false, then exp2 will be evaluated. This behavior is mandated by the standard.
So, in the expression 1 || printf("A"), there is no need to evaluate printf("A") as the result of the expression will be true in-spite of the evaluation of printf("A") due to the first expression which is 1.
Similarly, expressions are evaluated(from left to right) when logical AND operator && is used in between two expressions.

Logical operators

I have come across an answer and I can't seem to figure out why it's right.
So there are two int variables x and y and they represent 0x66 and 0x39 respectively.
The question asked what is the result value based on the expression.
x && y is apparently 0x01 (1)
x || y is 1
!x || !y is 0
x && ~y is 1
From what I was thinking, I thought as long as an argument was not zero it was considered true. So as long as x and y were some non-zero value then && operator would produce a 1, and of course as long as one of them is true the || operator would produce a 1.
So why is the third question 0? Is the ! different from the bitwise ~ operator? So originally x is 0101 0101 in binary since it's non zero it is true in the logical sense, but the ! of it would be false or would it do the one's complement of the number so its 1010 1010?
A boolean result is always true or false, and in C true is represented by 1 and false by 0.
The logical not operator ! gives a boolean result, i.e. 1 or 0. So if an expression is "true" (i.e. non-zero) then applying ! on that expression will make it false, i.e. 0.
In your example you have !x || !y. First !x is evaluated, and it evaluates to false, leading to !y being evaluated, and it also evaluates to false, so the while expression becomes false, i.e. 0.
From what I was thinking, I thought as long as an argument was not
zero it was considered true. So as long as x and y were some non-zero
value then && operator would produce a 1, and of course as long as one
of them is true the || operator would produce a 1.
This is all correct.
So why is the third question 0? Is the ! different from the bitwise ~ operator?
Yes. It is logical NOT. Just like the other logical operators && and ||, it only cares about if a variable has a non-zero value or not.
!0 will yield 1.
!non_zero will yield 0.
Note that all logical operators in C yield type int rather than bool, as an ugly, backwards-compatibility remain from the time before C had a boolean type. In C++ and other C-like languages, logical operators always yield type bool.
Similarly, true and false in C are actually just macros that expand to the integers 1 and 0. In other languages they are keywords and boolean constants.
Yes, ! is different from the bitwise not ~. It's a logical not. It yields either 0 or 1.
~(0x01) will 0x10 and
!(0x01) will 0x00
'~' is a bitwise operator.
'!' is a logical operator.

In C does the logical operator end if one side of a || is true? [duplicate]

This question already has answers here:
Is short-circuiting logical operators mandated? And evaluation order?
(7 answers)
Closed 9 years ago.
In C have the following:
return (abc(1) || abc(2));
If abc(1 == 1) returns true will then call abc(2)?
No, it won't. This is called "short-circuiting" and it is a common flow-control mechanism:
With a && b, b is only evaluated if a is true; if a is false, the whole expression must necessarily be false.
With a || b, b is only evaluated if a is false; if a is false, the whole expression may still be true.
No. It's guaranteed (by The Standard), that if abc(1) returns true, abc(2) will NOT be called.
If abc(1) returns false, that it's guaranteed, that abc(2) WILL be called.
It's similar with &&: if you have abc(1) && abc(2), abc(2) will be called ONLY IF abc(1) return true and will NOT be called, if abc(1) return false.
The idea behind this is:
true OR whatever -> true
false OR whatever -> whatever
false AND whatever -> false
true AND whatever -> whatever
This comes from the boolean algebra
If abc(1==1) returns true will then call abc(2) ?
No, it won't. This behavior is known as short-circuiting. It is guaranteed by C and C++ standards.
C11(n1570), § 6.5.13 Logical AND operator
Unlike the bitwise binary & operator, the && operator guarantees left-to-right evaluation; if the second operand is evaluated, there is a sequence point between the evaluations of
the first and second operands. If the first operand compares equal to 0, the second operand is not evaluated.
(Emphasis is mine.)
The same applies to the || operator.
abc(2) will be called only if abc(1) is false
According to C99 specification, logical OR operator says
The || operator guarantees left-to-right evaluation; there is a sequence point after the evaluation of the first operand. If the first operand compares unequal to 0, the second operand is not evaluated.
|| (logical comparison) breaks further checking, while | (bitwise comparison) doesn't.
You might also read: Difference between | and || or & and && for comparison
nop, the second abc(2) is called only if the left statement is false
In C, the logical || operator is tested from left-to-right, guaranteed. For the whole statement to be true, either condition can be true. So || keeps going from left to right until one condition is true, and then stops (or it gets to the end). So no, if abc(1) returns true then abc(2) will not be called.
Contrast with &&, which keeps going from left to right until one condition is false (or it gets to the end).
No. This is actually non trivial and defined in standard that logical operators are evaluated from left to right. Evaluation is stopped when the value can be determined with out further evaluation of operands. At least I am 100% sure for AND and OR.
This is non trivial problem, because therefore the evaluation of operands cannot be implicitly parallelized or optimized by reorganization of order, as the expected outcome could differ.
E.g. run-time troubles in wide-use cases such as if (*ptr && (ptr->number > other_number) )

Resources