Video Coming Soon...

Created by Zed A. Shaw Updated 2024-11-15 13:50:32

11: Boolean Tests

The topics so far have been boring, but now we're going to get into the exciting topic of Boolean Algebra! Aren't you excited?! To go back to Middle School and learn Algebra again?! I bet you are, so let's get to it.

In all seriousness, to write useful things in any programming language you need about four basic features:

  1. A way to input and output data.
  2. A way to store and alter data.
  3. A way to compare data with other data.
  4. A way to jump to different code locations.

Up to this point you've been studying #1 and #2 mostly. You can output to the screen (but not input yet), store data in variables, alter that data with math, and output it again. You next need to learn how to compare data so you can start making decisions in your code.

Comparing Data

The way you compare data in C++ is use a Boolean Operator which takes two variables or constants and returns either true or false depending on how they compare. The easiest one is == which simply tells you if the two things are equal:

int a = 1;
int b = 1;
bool is_eq = a == b;

A bool is the type of a boolean variable, and in the above code the is_eq should now be true after the comparison. You don't have to use variables for these comparisons:

int x = 1;
bool not_eq = x == 100;

This will compare x (which is 1) to the constant 100, and those aren't equal so now not_eq is false.

Boolean Test Syntax

These boolean tests almost always have the format of a OP b with OP being any of the operators listed in the next table. The only exception is the ! operator which simply inverts the boolean result. That means if you did !not_eq then it'll result in true because not_eq is false, and ! inverts that.

Did you get that? Don't worry, we'll practice that more in a bit.

Boolean Operators

OperationDescription
a == bIs Equal
a != bNot-Equal
a < bLess Than
a > bGreater Than
a <= bLess Than-Equal
a >= bGreater Than-Equal
a <=> bThree-way Comparison
!aNot (inverts bool)

Most of these are easy to understand and you'll explore them in the code example for this exercise. The only weird one is the a <=> b three-way comparison.

Three-way Comparison

I don't think this one comes up that often, but it's purpose is usually in sorting items. What it does is return a number that's less-than, equal, or greater-than zero depending on the values. The easiest way to see it is in this table:

WhenThenResult
a < ba <=> b-1
a > ba <=> b+1
a == ba <=> b0

This is an approximation of what the operator does, but C++ does a lot more with it that I can't really cover now. Just note this down as an advanced thing you probably won't run into for a while.

NOTE: This is sometimes called the "TIE Figher Operator" because it looks like a TIE Fighter ship from Star Wars <=>.

And / Or Operators

In addition to these comparison operators you also have two more that do "and" and "or" comparisons. One is a && b which asks, "Are both a AND b true?" The other is a || b which asks, "Is either a OR b true?" I actually say the word "and" in my head when I read && , so I would read a && b as "aye and bee." Same for a || b but I say, "aye or bee" as I read || as "or" when I read it.

The a && b tests if both a and b are true. If they are then this becomes true. If not it becomes false. The a || b tests if at least one of a or b is true, and if one is then it is true. Otherwise a || b will be false if both are false.

This is a complicated one, so we'll cover it a little in the code sample, then you'll learn even more in the next exercise.

The Code

To play with these boolean tests we'll make a little ex11.cpp file and try them out:

View Source file ex11.cpp Only

#include <iostream>
#include <fmt/core.h>

using namespace std;
using namespace fmt;

int main() {
  int peanuts = 1000;
  int people = 100;

  println("More {} peanuts and {} people.", peanuts, people);

  bool test = peanuts > people;
  println("More peanuts than people? {}", test);

  test = peanuts < people;
  println("Less peanuts than people? {}", test);

  test = peanuts == people;
  println("Are peanuts equal to people? {}", test);

  test = peanuts >= 1000;
  println("Are there more peanuts or equal to 1000? {}", test);

  test = people <= 500;
  println("Are there fewer or equal people than 500? {}", test);

  println("What if we not that? {}", !test);

  // combine with some math
  test = peanuts == people * 10;
  println("What about 10x the poeple? {}", test);

  bool tenth_peanuts = peanuts / 10 == people;
  println("Maybe 1/10th the peanuts? {}", tenth_peanuts);

  bool less_peanuts = peanuts - 100 == people;
  println("If I eat 100 peanuts? {}", less_peanuts);

  bool and_test = tenth_peanuts && less_peanuts;
  // remember multi-line strings?
  println("Are there 1/10th the peanuts of people\n"
      "\tAND are there the same number of people "
      "as peanuts - 100? {}", and_test);

  bool or_test = tenth_peanuts || less_peanuts;
  println("Same but either there's 1/10th "
      "peanuts OR peanuts minus 100? {}", or_test);

  return 0;
}

Always remember that this code is nonsensical on purpose. There's no meaning behind peanuts and people, and that's so you don't obsess over the "correctness" of some arbitrary math problem when you should be trying to figure out how these operators work. Definitely pay attention to the and_test and or_test to try to understand it.

What You Should See

When you run this code you should see this:

More 1000 peanuts and 100 people.
More peanuts than people? true
Less peanuts than people? false
Are peanuts equal to people? false
Are there more peanuts or equal to 1000? true
Are there fewer or equal people than 500? true
What if we not that? false
What about 10x the poeple? true
Maybe 1/10th the peanuts? true
If I eat 100 peanuts? false
Are there 1/10th the peanuts of people
        AND are there the same number of people as peanuts - 100? false
Same but either there's 1/10th peanuts OR peanuts minus 100? true

If you see something different, then check your code compared to mine.

Breaking It

Breaking this is a little difficult, but try a few of these ideas:

  1. See what happens when you try to compare float and double values. You can probably come up with some math that will create what seems like two equal float values that C++ says are not equal.
  2. Try to break fmt::println by using the fmt::println formatting options to give the wrong types.

Most of the ways you'll break comparisons boil down to either math that doesn't work, or converting types. Try to see what happens when you convert int to double, convert a string number to double, and complex floating point (decimal) math.

Further Study

  1. Do more combinations of math operators from Exercise 10 and the boolean operators. You should be trying to combine everything you can to see if it'll work.
  2. Did you type the code a little at a time and run it frequently? If not delete it and do it again. You thought I forgot about that didn't you?
  3. ADVANCED How many different ways can you combine the boolean operators with the && (and) and || (or) operators?
  4. ADVANCED When combining many operators, use ( and ) to group them together. This solves any problems of "precedence" where you're not sure if one operator is calculated before another. When in doubt, "parens it out." That means put () around the stuff you want to go first. Try doing that some to see the results.
Previous Lesson Next Lesson

Register for Learn C++ the Hard Way

Register to gain access to additional videos which demonstrate each exercise. Videos are priced to cover the cost of hosting.