Video Coming Soon...

Created by Zed A. Shaw Updated 2024-10-28 08:02:26

10: Math Expressions

This exercise will be another challenge exercise where you are expected to complete a piece of code on your own. With challenges I recommend you take your time. Ideally some challenges could take you days but shouldn't take more than 1 week. If you find yourself completely stuck remember this one important rule:

You cannot figure out what code does by only looking at it.

You must either use a debugger, or print out variables to find out what's actually going on while it runs. If you catch yourself staring at the code for hours on end hoping the solution will jump out at you, go take a break. Go for a walk, play a video game, read a book, or anything that's not programming. When you come back, stop reading the code and start interrogating the code.

This challenge is going to teach you more about using print debugging to interrogate the code.

Math Operations

C++ has many all the math operations you would expect, and many you haven't seen in a normal math class. The common operations you'll use are:

OperationDescription
a + bAddition
a - bSubtraction
a * bMultiplication
a / bDivision
a % bModulus not PERCENT!
a = bAssignment
a += bAdd assign
a -= bMinus assign
a *= bMultiply assign
a /= bDivide assign
a %= bModulus assign not PERCENT!
++aPre-increment
--aPre-decrement
a++Post-increment
a--Post-decrement
+aPositive
-aNegative

You should be looking for patterns in this list to make it easier to remember. There's only three patterns you need to know:

a OP b
OP here means "operator", so it's the symbols +, -, etc. This is your typical math of 10 + 34 but remember that a and b can be a variable, number, or any other rvalue.
a OP= b
This combines assignment with the OP so it's simply a convenient way of writing a = a OP b. For example, x += 10 is the same as x = x + 10.
OPa or aOP
This is usually a single action on a that produces a new value. ++a increments a which is the same as typing a = a + 1. In C++ code you almost always want ++a, even though I constantly get this wrong because of other languages.

Pre- vs. Post- Footguns

One thing about C++ that I still find annoying is the difference between Post-increment (or decrement) and Pre-increment. When you use ++a the value of a is incremented before it's used in the expression, but when you use a++ the value of a is used, then it's incremented. This ends up being confusing enough that I find it introduces tiny little bugs only because you put a variable in the wrong place.

I'd say, always use ++a and --a as it will most likely do what you expect, and if you see me not doing that in the code let me know. It's a very easy mistake to make, which is a very common thing in programming.

Why are programming languages so full single-letter error traps? Welcome to programming! You just encountered a "footgun." A footgun is some feature of a language that is so easy to use wrong that it's like walking around with a loaded gun designed to only blast you in the foot. Any time run into a footgun you should come up with a way to just not use it.

For example, you would probably do better to rarely use ++ and --. Instead, try using a+1 in most places, and only ++a when you're sure that's what you actually want. It's the same number of characters, but you if you accidentally type 1+a you still get the same result of 1 added to a. If you type a++ you get a and then later it's incremented, which is probably not what you want.

The Code

You'll now enter in this code but I have to warn you: This code is nonsensical on purpose. This means that there is absolutely no meaning behind the names of the variables. I am not actually calculating the number of tigers in the world using peanuts and people. The reason I use nonsense variable names is I want you to focus on three important things:

  1. The names of variables don't matter to the compiler, but people think they do. You can name them anything you want, so pick names that tell you what they're doing.
  2. I want you to focus on what the operations do, not on some arbitrary math puzzle. I've found that if I put a math puzzle into the code people obsess over the "correctness" of the puzzle rather than learning how the operations work. The point of this exercise is math operations, not some made up SAT test question.
  3. When the variable names are nonsense you are free to play with the operations to see what they do. I've found when I make a real math problem people are afraid of changing the operations for fear of getting the "wrong answer." There is no answer here. It's a playground for trying the operations.

With that out of the way, get this code working. The only new thing here is a few of the operations you learned about.

View Source file ex10.cpp Only

#include <fmt/core.h>

using namespace fmt;

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

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

  peanuts += 10;
  people -= 10;

  println("After += and -= peanuts={}, people={}", peanuts, people);

  int tigers = peanuts * people;
  long lots_of_tigers = tigers * 5;

  println("tigers={}, lots_of_tigers={}", tigers, lots_of_tigers);

  double fewer_tigers = lots_of_tigers / 23;
  println("fewer_tigers={}", fewer_tigers);

  fewer_tigers /= 43.0f;
  println("fewer_tigers again={}", fewer_tigers);

  ++tigers;
  println("one more tiger={}", tigers);
  return 0;
}

About Hacking

An important part of programming is "hacking on stuff." "Hacking" has two meanings:

Computer Security Hacking
This is the act of breaking into a computer through a flaw in the software. It can be done by bad people committing crime, or good people trying to find flaws so they can be fixed and stop the bad people.
Jugaad Hacking
I can't think of another way to put it, but the other use of hacking is very similar to the word "Jugaad" which means to "innovate a fix, create simple workaround, solutions that bend the rules, or using resources in novel ways." It's used in many areas outside of hacking and I think of it as "finding new ways to fix or use things."

In this course you're sort of learning both, because you need both in programming. When you're doing the Break It you're learning Computer Security Hacking skills. When you do the Further Study you're learning Jugaad Hacking skills.

To keep things simple, I'm going to start saying "hacking" when I want you to mess around and see what you can do (Jugaad Hacking). I'll use "exploiting" when I want you to try to break your code like a Computer Security Hacker.

The Challenge

You are now going to do some hacking. Your challenge is to find a way to use every operator in the table above, but you've got to use it in the weirdest calculations you can. Your job is to try to combine these operators in as many different ways, using all the types like long double and unsigned int, to produce strange values. As you use an operation be sure to print it out the way I'm doing it.

When you're done this file should be fairly large, but more importantly you'll need to do your printing of the variables in the style I'm using here. This is the Debug Printing practice I mentioned in the beginning of the exercise. Debug printing is very useful when you're hacking because it lets you see what's going on while the code runs using no additional tools.

Break It

Now you'll do some exploiting of your code. You should try to see if you can really mess with your math to produce very wrong numbers. The common way you'll do this is to give numbers that are too large for the type of variable. For example, doing multiplication (*) with two large numbers, but assign them to an int.

Try this, then I want you to add {} around the right hand side of assignments with this problem. for example, in the current code I can do this:

double fewer_tigers = {lots_of_tigers / 23};

You should get a warning in many places where you can cause math bugs. The {} notation around a variable or expression tell the c++ compiler that you do not want certain types of implicit conversion that can cause errors. It's not perfect, but try it to see what works and does not work.

Further Study

  1. C++ also comes with many math functions. Read through the Common math function documentation and see how many you can use in your monstrous hacked up ex10.cpp file.
  2. Read the fmt Syntax Documentation and add type specifiers to your {} for each type. See how complex you can get with the format syntax.
  3. The fmt library is able to detect when you use the wrong type, so try to cause these errors with the syntax.
  4. ADVANCED Read Documentation for implicit conversions and try to understand what you can. Always remember that you're not expected to understand everything. Study what you can, and remember where this is so you can come back to it when you need it later.
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.