Magical Mystery XOR
Jake Witcher
Posted on March 13, 2021
Binary logical operators are fundamental to software development and chances are you use them almost every time you write code. The operators &&
(and) and ||
(or) fall into this category and are regularly found in predicates for control flow statements in application code.
if (a && b) {
// do something...
} else if (a || b) {
// do something else...
}
&&
and ||
are referred to as binary logical operators because they perform an operation on two values (binary) and the two values (or operands) must be propositional expressions that evaluate to either true or false (logical).
Combining two propositional expressions with a binary logical operator produces a new propositional expression which is itself a valid operand for a binary logical operator. This means that we can use an expression with a logical operator as one of the operands of another expression, for example (a && b) || c
where the expression (a && b)
serves as the left operand of the ||
operator.
While less common in most application code, there is a third binary logical operator that can be used in control flow statements. It is known as the xor operator or the exclusive or operator. Not all programming languages have a built in xor operator but of those that do, the symbol ^
is often used to represent xor in code, allowing for expressions like a ^ b
and (a ^ b && c)
.
The && and || Operators
Before getting into what exactly ^
does and when to use it, let's first take a brief look at &&
and ||
so that we can consider the xor operator as it relates to and and or.
The operator &&
evaluates to true if both operands in the expression evaluate to true, otherwise it evaluates to false. The relationship between &&
and all possible combinations of left and right operands are expressed in the following truth table where column a
represents the left operand of an expression, column b
represents the right operand of an expression, and column &&
represents the result of applying the &&
operator to both a
and b
.
-----------------------
a | b | &&
=======================
True | True | True
-----------------------
True | False | False
------------------
False | True | False
------------------
False | False | False
------------------
In contrast to &&
, the operator ||
evaluates to true if either one or the other operand in the expression evaluates to true or if both operands evaluate to true. If both operands are false, then the ||
expression will be false.
------------------
a | b | ||
=======================
True | True | True
------------------
True | False | True
------------------
False | True | True
------------------
False | False | False
------------------
The ^ Operator
Then there is the ^
operator. It evaluates to true if either operand in the expression evaluates to true but not if both operands evaluate to true. If both operands are false or if both operands are true, the ^
expression will evaluate to false. This is what the exclusive in exclusive or is communicating. For the expression to evaluate as true, one or the other operand must be true, not both. One of them must be exclusively true.
------------------
a | b | ^
=======================
True | True | False
------------------
True | False | True
------------------
False | True | True
------------------
False | False | False
------------------
You may come across languages that have a bitwise xor operator however this is not the same as the logical xor operator. Conceptually they are similar but in practice they are used for different purposes. It is outside the scope of this blog post to discuss bitwise operators and their relationship to logical operators however it is a topic worth exploring separately. For now it is important to know that they are not the same and that the focus of this blog post is on logical operators, not bitwise.
Using Exclusive Or in Code
The xor operator should be used when you require one and only one of two expressions to be true. For languages that do not have an xor operator, it is possible to check if only one expression is true however it is more verbose and does not communicate intent as clearly.
If the language you are working with has an xor operator, using it will make your code easier to read at a glance. It will clearly communicate the purpose of your code — to find an exclusively true expression.
// these expressions takes much longer to read and understand
boolean c = (a || b) && !(a && b)
boolean d = (a && !b) || (!a && b)
// using xor clearly communicates the purpose of the expression
boolean e = a ^ b
Posted on March 13, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.