10 min read

Basic Math

The Crash Course

With a basic understanding of variables, it is time to turn our attention to the thing computers were designed for: math. Don’t worry if you’re not a math geek. We’re not talking about anything worse than basic arithmetic.

We’ll start with addition and subtraction, then cover multiplication, division, and remainders. After that, we’ll look at the “sign” operators (+ and - signs in front of things). We’ll also cover order of operations and how to override that with parentheses. We’ll finish with some shortcuts for updating variables with math operations.

Addition and Subtraction

Doing basic arithmetic in C# is pretty easy.

Let’s start with addition (which we actually previewed in the previous tutorial):

int a = 3 + 4;

The + sign is an operator, and using it here will cause the computer to take the thing on the left and add it to the thing on the right. By the time the above line finishes executing, the variable a will hold a value of 7.

Subtraction works similarly:

int b = 5 - 2;

Both of these operators work on any type of expression, not just literals. That means you could use a variable in the expression instead:

int c = a - b;

And, of course, since addition is an expression, and both things you’re adding also must be expressions, you can combine them in complex ways:

int d = a + b - c + 4;

Multiplication, Division, and Remainder

Multiplication and division are not really any harder or more complex than addition and subtraction, though the symbols we use may not be so obvious. The * symbol is used for multiplication and the / symbol is used for division.

int dozen = 4 * 3;
int halfDozen = dozen / 2;

There is another operator, related to division, that also deserves attention: the remainder operator (%) which computes the remainder of a division operation.

note

The remainder operator is also sometimes called the modulus or mod operator. These terms are often used interchangeably with the remainder operator, though there’s a difference with negative numbers. (Modulus always gives you positive values, while remainder can give you negative values when the numbers involved were negative.)

To illustrate the remainder operator, consider this math problem, similar to what you likely saw in elementary school: “If we have 23 apples and share that among 4 people, how many whole apples does each person get, and how many will be left over?” In code, that could look like this:

int totalApples = 23;
int people = 4;

int applesPerPerson = totalApples / people;
int remainder = applesPerPerson % people;

Console.WriteLine("Each person will get " + applesPerPerson);
Console.WriteLine("There will be " + remainder + " left over.");

The remainder operator is actually surprisingly useful, mostly because it can be used to tell you if some number is a multiple of another number. We’ll see examples of that in future tutorials.

Math and Types

When you’re doing math and using operators, you must pay attention to the types involved. In most situations, operations like addition and multiplication only work on two things of the exact same type. You can use + only on two int values or two float values (or even two string values!), for example. And they also generally produce a new value of the same type as their inputs.

To illustrate what I mean, consider the differences between these two lines:

int a = 3 + 4;
float b = 3.0f + 4.0f;

3 and 4 are both int literals, while 3.0f and 4.0f are both float literals. So the first line does addition with two int values and produces a new int value (7), while the second line does addition with two float values and produces a new float value (7.0f).

The good news is that if you have a mismatch in types, you can convert between the types.

In fact, C# will automatically convert certain types for you. The automatic conversions are ones where you won’t lose data.

For example, C# will automatically upgrade an int to a long, if necessary, because the long type can correctly represent every possible int value. So the following works fine:

int a = 0;
long b = 100000000;
long c = b + a;

On that last line, b + a represents addition between two different types (a long on the left and an int on the right). But the int will be converted (“promoted”) to a long automatically, and the result will be another long. (That also means that you’d have a problem if c’s type was int instead of long.)

warning

If you ever attempt an operation where the types don’t match up and where there isn’t an automatic conversion, when you compile your program, it will fail and tell you about the type conversion error. Be prepared to see these types of compiler errors.

In other situations, the computer can convert from one type another, but won’t do so automatically. Instead, you can do it by request, by performing a cast . To cast from one type to another, you place the type you want to convert to inside of parentheses, immediately before the value or expression:

int a = 0;
long b = 1;
int c = (int)(b + a);

Not every type can be converted to every other type. But most situations where it makes sense, it is allowed.

Unary + and - Operators

While we have already seen the + and - operators, they both come in a second flavor as well.

Some operators work by placing it between two values. Addition is a good example of this: 1 + 9. Operators that work with two values are called binary operators .

Some operators only require one value to function. These are placed just before or just after the value (or expression!). Operators that only have one thing (operand ") that they work with are called unary operators . The negative sign is a unary operator: -a. This operator takes whatever value it is working with and produces its negative. 4 becomes -4. -2.5 becomes +2.5.

This can be used as a part of a larger expression as well:

int a = 5;
int b = -(a * 2 + 1);

There is also a unary + operator, though it doesn’t actually change the value at all. Instead, it is provided to make “parallel” code that differs only by sign easier to understand:

int a = 5;
int b = -a * 2;
int c = +a * 2;

The + doesn’t actually do anything mathematically, here, but it helps vertically align the code on the two lines to make it a bit easier to see that they’re a matching pair.

Order of Operations and Parentheses

While we’ve only talked about seven operators so far (+, -, *, /, %, and unary + and -), C# actually has a very large set of operators–over 60.

If an expression has multiple operations strung together, the computer needs to figure out what order to perform them in. Each programming language–and math itself–has a set of rules called the order of operations that determines which operations to do first.

For example, in the expression a + b * c, do you do the addition or multiplication first? The order you perform the operations has an impact on the answer. Suppose a is 2, b is 3, and c is 4. If you do the addition first, 2+3 is 5, and then multiply by 4 to get a final answer of 20. If you do the multiplication first, 3 * 4 is 12, and then add 2 and 12 to get a final answer of 14.

The rules that compromise order of operations are divided into two parts: operator precedence –which operators are evaluated first–and operator associativity –whether two operations of the same precedence are evaluated left to right or right to left.

In C#–as well as in math and any other programming language–these rules are kind of complicated. We won’t cover them all in great detail.

The short version is that the order of operations in C# match the ones you are familiar with in math, so there shouldn’t be too many surprises.

The slightly more complicated answer is that the precedence is as follows:

  1. Unary + and -.
  2. The multiplicative operators: *, /, and %.
  3. The additive operators: + and -.

That is, given an expression, all negations will be evaluated first, then all multiplies, divides, and remainders from left to right, then all additions and subtractions from left to right. In the expression a * 2 - 4 + -b, these operations will be computed in the following order:

  1. The -b is evaluated.
  2. The a * 2 is evaluated.
  3. The subtraction between what you found in step 2 and 4 is evaluated.
  4. The addition between what you found in step 3 and step 1 is evaluated.

Using Parentheses to Change the Order of Operations

If you ever need to force the ordering to be different from what the order of operations dictates, you can use parentheses. Everything inside of parentheses is evaluated (using the same order of operations rules) before everything else:

int x = (2 + 3) * 4;

Without the parentheses above, the multiplication would happen first. With the parentheses, the addition happens first.

Parentheses can be nested –placed inside of each other to form multiple levels:

int y = ((2 + 3) * 4 - 6) / 3;

Compound Assignment Operators

Before we move on, let’s look briefly at a shortcut.

In programming, we often have situations where we want to update a variable based on what is currently in it. For example, “Whatever is in a right now, I want to add one to it.”

The long way to do this is like so:

a = a + 1;

If you’ve done much algebra, that might look a little strange to you. From a math perspective, it is nonsense. There is no number equal to itself plus one.

But this isn’t math, and = does not establish an equality relationship. The = assigns values to a variable instead.

In this case, the expression a + 1 is evaluated–pulling the current value out of a, and then adding one to it. That new value is then put back into a. If a was 3 at the start, this could would retrieve the value in a (the 3), add one to it (4) and store that value back in a.

This type of scenario is quite common, so some shortcuts exist. The following two lines are exactly equal:

a = a + 1;
a += 1;

That += is called a compound assignment operator . There is one for addition, subtraction, multiplication, division, and remainders:

a += 1;
a -= 2;
a *= 3;
a /= 4;
a %= 5;

In fact, adding one or subtracting one is so common that they have a name and yet another special operator.

Adding one to a variable is called incrementing it. The ++ operator will add one to the variable it uses:

a++;

Subtracting one from a variable is called decrementing it. The -- operator will subtract one from the variable it uses:

a--;

There is a lot of math to be done in programming, and especially game programming. We’re really only scratching the surface here, though in a couple of tutorials, we’ll come back and dig a bit deeper on some of these topics.