Boolean Operators Combining booleans
Key Takeways
Video Addendum
Boolean operators
Just like you are able to operate on int
s with multiplication, addition, subtraction, division, and modulo, you can also operate on booleans. These are called boolean operators. The boolean operators are:
- not
!
- and
&&
- or
||
- xor
^
For each of the operators, you can both read the summary of how it works and see what it’s result will be by using the truth tables below.
not A
or !A
is true
if A is false
, and vice versa.
A | !A |
---|---|
true |
false |
false |
true |
A and B
or A && B
is true
whenever both A and B are true
, otherwise its false
.
A | B | A && B |
||
---|---|---|---|---|
true |
&& | true |
= | true |
true |
&& | false |
= | false |
false |
&& | true |
= | false |
false |
&& | false |
= | false |
A or B
or A || B
is true
whenever any of A or B are true
, otherwise its false
.
A | B | A || B |
||
---|---|---|---|---|
true |
|| | true |
= | true |
true |
|| | false |
= | true |
false |
|| | true |
= | true |
false |
|| | false |
= | false |
A xor B
or A ^ B
is true
whenever only one of A or B are true
, otherwise its false
. xor is short for exclusive-or.
A | B | A ^ B |
||
---|---|---|---|---|
true |
^ | true |
= | false |
true |
^ | false |
= | true |
false |
^ | true |
= | true |
false |
^ | false |
= | false |
Use cases
Often you’ll be using boolean operators to express what you want your code to do. For example you may have the following problem assigned to you.
Ask the user for a number.
If it divides evenly by both 3 and 5, print "DONG!".
Otherwise, if the number divides evenly by 3, print "Tick".
Otherwise, if the number divides evenly by 5, print "Tock".
In all other cases print out the number.
int main() {
// Asking the user for a number.
int number = GetUserInput();
// Using variables to get the divisbility of the number.
bool divides_by_3 = (number % 3 == 0); // True if number evenly divides 3.
bool divides_by_5 = (number % 5 == 0); // True if number evenly divides 5.
// If the number divides by 3 AND 5.
if (divides_by_3 && divides_by_5) {
std::cout << "DONG!";
}
// If the number divides only by 3 (but doesn't divide by 5).
if (divides_by_3 && !divides_by_5) {
std::cout << "Tick";
}
// If the number divides only by 5 (but doesn't divide by 3).
if (divides_by_5 && !divides_by_3) {
std::cout << "Tock";
}
// If a number doesn't divide by 3 and 5.
if (!divides_by_3 && !divides_by_5) {
std::cout << number;
}
return 0;
}
This is how you read each of the if
clauses.
// If divides_by_3 is true AND divides_by_5 is true, then execute the block.
// This will trigger only when both divides_by_3 and divides_by_5 are true.
if (divides_by_3 && divides_by_5)
// If divides_by_3 is true AND NOT (divides_by_5 is true), then execute the block.
// This will trigger only when divides_by_3 is true and divides_by_5 is false.
if (divides_by_3 && !divides_by_5)
// If divides_by_5 is true AND NOT (divides_by_3 is true), then execute the block.
// This will trigger only when divides_by_3 is false and divides_by_5 is true.
if (divides_by_5 && !divides_by_3)
// If NOT (divides_by_3 is true) AND NOT (divides_by_5 is true), then execute the block.
// This will trigger only when both divides_by_3 and divides_by_5 are false.
if (!divides_by_3 && !divides_by_5))
De Morgan’s Law
One important concept to grasp regarding boolean operators is that you can combine values in different ways and still get the same result. De Morgan’s Law specifically states:
!(a && b)
is the same as(!a || !b)
.!(a || b)
is the same as(!a && !b)
. Notice that De Morgan’s Law gives us a way to swap ORs||
with ANDs&&
and vice versa.
Building Truth Tables
bool var_a = /*either true or false*/;
bool var_b = /*either true or false*/;
// option_0 = NOT (var_a OR var_b)
bool option_0 = !(var_a || var_b);
// option_1 = (NOT var_a) AND (NOT var_b)
bool option_1 = ((!var_a) && (!var_b));
Let’s start by building a truth table. We have 2 inputs - var_a
and var_b
- and 2 outputs - option_0
and option_1
.
var_a | var_b | option_0 !(var_a || var_b) |
option_1 ((!var_a) && (!var_b)) |
---|---|---|---|
We know var_a
can be either true
or false
so lets fill that in.
var_a | var_b | option_0 !(var_a || var_b) |
option_1 ((!var_a) && (!var_b)) |
---|---|---|---|
true |
|||
false |
We also know var_b
can be either true
or false
, however this is the case for all possibilities of var_a
. This is shown using this table.
var_a | var_b | option_0 !(var_a || var_b) |
option_1 ((!var_a) && (!var_b)) |
---|---|---|---|
true |
true |
||
true |
false |
||
false |
true |
||
false |
false |
Now we just fill in the values for our outputs options_0
at first.
var_a | var_b | option_0 !(var_a || var_b) |
option_1 ((!var_a) && (!var_b)) |
---|---|---|---|
true |
true |
!(true || true) |
|
true |
false |
!(true || false) |
|
false |
true |
!(false || true) |
|
false |
false |
!(false || false) |
Simplifing inside the ( )
we get:
var_a | var_b | option_0 !(var_a || var_b) |
option_1 ((!var_a) && (!var_b)) |
---|---|---|---|
true |
true |
!(true) |
|
true |
false |
!(true) |
|
false |
true |
!(true) |
|
false |
false |
!(false) |
Simplifying again we get:
var_a | var_b | option_0 !(var_a || var_b) |
option_1 ((!var_a) && (!var_b)) |
---|---|---|---|
true |
true |
false |
|
true |
false |
false |
|
false |
true |
false |
|
false |
false |
true |
If you follow a similar process for option_1
, you will get the final table:
var_a | var_b | option_0 !(var_a || var_b) |
option_1 ((!var_a) && (!var_b)) |
---|---|---|---|
true |
true |
false |
false |
true |
false |
false |
false |
false |
true |
false |
false |
false |
false |
true |
true |
How are they the same? De Morgan’s Law!
Assignment
- Write truth tables for the following expressions assuming
var_a
,var_b
, andvar_c
are boolean inputs.var_c || !var_c
var_a && !var_a
!var_a ^ (var_a || var_b)
(Remember^
is XOR).var_a && (var_a || var_b)
(var_b && var_a) || (var_c && !var_b)
var_c || (!var_c && var_a) || !(!var_c && !var_b)
- Optional: What are simpler, equivalent expresions for each of the ones above that would always produce the same truth table?
- What will Code Sample 0 output to the console for the user inputs below? Figure out the answer without running the code. Then run the code in a Repl to double check your answer. Remember to estimate all new lines as well whenever stating what is printed out.
x = 5
,y = 12
x = 1000
,y = -2
x = 11
,y = 23
x = -8
,y = 2
- Write an expresion that produces an equivalent Truth Table to
A ^ B
without using^
.-
Hint
Try using&&
!
and||
-
- Use De Morgan’s Law to write equivalent expressions without using
&&
.A && (!B && !C)
B && (!A && C) && (!A && !B)
Code Samples
Sample 0
int main() {
int x = GetUserInput();
int y = GetUserInput();
if (x < 10) {
std::cout << "Small ";
}
if (x < 10 && !(y % 11 == 0)) {
std::cout << "Medium " << std::endl;
}
if (x > 20 || (y < x) ^ !(x % 3 != 2)) {
std::cout << "Large ";
}
if (y < 10) {
std::cout << "Giant ";
}
std::cout << "Case" << std::endl;
}
End of Assignment Checklist
- I finished all the assignments.
- I shared my assignments with others.
- I provided feedback for assignments of at least 2 others.
- I addressed the feedback from others and thanked them for the review.