Every program calculates something: a total price, a score, the time left on a timer, the position of a character in a game. In C++, calculations use operators like +, -, * and /, and a set of maths functions from the <cmath> library.
C++ is close to the hardware, and its arithmetic follows the rules of the types you use. Dividing one int by another throws away the fraction, so 7 / 2 is 3. An int that grows too large doesn't become a bigger number; it overflows, which in C++ is a real bug with unpredictable results. Learning these rules early saves hours of confusion later.
In this lesson you'll use the arithmetic operators, mix integers and decimals correctly, convert between types with static_cast, use shortcuts such as ++ and +=, call the common functions in <cmath>, and generate random numbers the modern C++ way.
Arithmetic operators
| Operator | Meaning | int example | double example |
|---|---|---|---|
+ | Add | 7 + 2 is 9 | 7.5 + 2 is 9.5 |
- | Subtract | 7 - 2 is 5 | 7.5 - 2 is 5.5 |
* | Multiply | 7 * 2 is 14 | 1.5 * 2 is 3 |
/ | Divide | 7 / 2 is 3 | 7.0 / 2 is 3.5 |
% | Remainder | 7 % 2 is 1 | not allowed |
When both sides are integers, / does integer division and drops the decimal part. If either side is a double, the result is a double. The remainder operator % only works with integers; use fmod() from <cmath> for decimals. Note that cout prints 3.0 as just 3.
static_cast and precedence
To divide two int values and keep the decimals, convert one of them with static_cast:
int total = 7, people = 2;
double each = static_cast<double>(total) / people; // 3.5
int whole = static_cast<int>(9.99); // 9static_cast<int> truncates towards zero rather than rounding. You'll also see the older C-style cast (double)total; static_cast is preferred in modern C++ because it's easier to spot and safer. Operators follow the usual maths order: brackets, then *, /, %, then + and -.
Increment and compound assignment
| Shortcut | Same as |
|---|---|
x++ or ++x | x = x + 1 |
x-- or --x | x = x - 1 |
x += 5 | x = x + 5 |
x -= 5, x *= 2, x /= 2, x %= 3 | and so on |
Inside a bigger expression, x++ uses the old value and then adds one, while ++x adds one first. Keep increments on their own line, or in a for loop header, and the difference never matters. Never change the same variable twice in one expression, like i = i++ + 1.
cmath, overflow and random numbers
#include <cmath> gives you sqrt(x), pow(base, exp), abs(x), round(x), ceil(x) (round up), floor(x) (round down) and many more.
An int usually holds up to about 2.1 billion. Going past it is undefined behaviour for signed integers: the program might wrap round, crash or behave strangely. Use long long for big values and check limits with std::numeric_limits<int>::max() from <limits>.
For random numbers, modern C++ uses <random>:
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<int> dice(1, 6);
int roll = dice(gen);Rounding and dividing negative numbers
Negative numbers are where the rounding functions start to differ. Compare what each one does with -2.5:
| Call | Result | Rule |
|---|---|---|
round(-2.5) | -3 | Nearest whole number; halves go away from zero |
floor(-2.5) | -3 | Always down, towards minus infinity |
ceil(-2.5) | -2 | Always up, towards plus infinity |
trunc(-2.5) | -2 | Drops the decimals, towards zero |
static_cast<int>(-2.7) | -2 | Also towards zero |
Integer division follows the same "towards zero" rule, so -7 / 2 is -3, not -4. The remainder takes the sign of the left-hand number: -7 % 2 is -1 and 7 % -2 is 1. That matters when you test for odd numbers: n % 2 == 1 is false for -3, so write n % 2 != 0 instead.
To round to a number of decimal places, scale up, round and scale back down:
double pi = 3.14159;
double twoPlaces = round(pi * 100) / 100; // 3.14If you only need the rounded value for display, the formatting tools in the formatting lesson are simpler and leave the stored number untouched.
C++ Operators Syntax
Operators and cmath
a + b a - b a * b a / b a % b
static_cast<double>(a) / b
x++; x--; x += 5; x *= 2;
#include <cmath>
sqrt(x) pow(b, e) abs(x) round(x) ceil(x) floor(x)
#include <random>
mt19937 gen(random_device{}());
uniform_int_distribution<int> d(1, 6);
d(gen);C++ Operators Summary
/between two ints drops the decimals;%gives the remainder and needs integers.- Use
static_cast<double>(x)to get decimal division; casting to int truncates. ++,--,+=and friends update a variable using its current value.<cmath>provides sqrt, pow, abs, round, ceil and floor.- Signed overflow is undefined behaviour; use long long for big numbers and
<random>for random values.
C++ Operators Examples
Each example shows the code, the output it produces and what each part does.
Minutes, hours and even numbers
#include <iostream>
using namespace std;
int main() {
int minutes = 135;
int hours = minutes / 60;
int left = minutes % 60;
cout << minutes << " minutes = " << hours << " h " << left << " min" << endl;
for (int n = 1; n <= 6; n++) {
if (n % 3 == 0) {
cout << n << " is a multiple of 3" << endl;
}
}
return 0;
}135 minutes = 2 h 15 min
3 is a multiple of 3
6 is a multiple of 3Line-by-line explanation
- Line 6Integer division gives the whole hours: 2.
- Line 7The remainder is what's left over: 15 minutes.
- Line 11A remainder of 0 means n divides exactly by 3.
Averages, casting and rounding
#include <iostream>
#include <cmath>
using namespace std;
int main() {
int total = 17;
int count = 4;
cout << "Wrong average: " << total / count << endl;
double avg = static_cast<double>(total) / count;
cout << "Right average: " << avg << endl;
cout << "Rounded: " << round(avg) << endl;
cout << "Rounded up: " << ceil(avg) << endl;
cout << "Truncated: " << static_cast<int>(4.99) << endl;
return 0;
}Wrong average: 4
Right average: 4.25
Rounded: 4
Rounded up: 5
Truncated: 4Line-by-line explanation
- Line 9Both values are ints, so the .25 is lost.
- Line 10Casting total to double first makes the division keep its decimals.
- Lines 12 to 13round goes to the nearest whole number; ceil always rounds up.
- Line 14A cast simply cuts off the decimals.
Shortcuts, powers and a dice roll
#include <iostream>
#include <cmath>
#include <random>
using namespace std;
int main() {
int score = 0;
score += 50;
score *= 2;
score -= 15;
score++;
cout << "Score: " << score << endl;
cout << "2^10 = " << pow(2, 10) << endl;
cout << "sqrt(144) = " << sqrt(144) << endl;
cout << "abs(-7) = " << abs(-7) << endl;
mt19937 gen(random_device{}());
uniform_int_distribution<int> dice(1, 6);
cout << "You rolled a " << dice(gen) << endl;
return 0;
}Score: 86
2^10 = 1024
sqrt(144) = 12
abs(-7) = 7
You rolled a 4Line-by-line explanation
- Lines 8 to 110, then 50, 100, 85 and finally 86.
- Lines 14 to 15pow and sqrt return doubles, which cout prints without a trailing .0.
- Lines 18 to 20A random number generator and a distribution from 1 to 6. The roll changes every run.
Common C++ Operators Mistakes
Integer division by accident
double half = 1 / 2; // 0double half = 1.0 / 2; // 0.5Using % with doubles
double r = 7.5 % 2; // compile error#include <cmath>
double r = fmod(7.5, 2); // 1.5Overflowing an int
int bytes = 3000000 * 1000; // overflow: undefined behaviourlong long bytes = 3000000LL * 1000;The LL suffix makes the multiplication itself use long long.
C++ Operators in Real Projects
Arithmetic in C++ programs
Games use C++ arithmetic every frame to move characters and detect collisions, and % to wrap around screen edges or cycle animations. Embedded systems in cars and appliances carefully choose integer types to avoid overflow. Simulations, finance engines and graphics programs rely on <cmath> and <random> for speed and accuracy.
C++ Operators FAQ
Does C++ have a power operator?
No. ^ exists, but it's the bitwise XOR operator, so 2 ^ 3 is 1, not 8. Use pow(2, 3) from <cmath>, which returns a double. For small whole-number powers such as squares, x * x is simpler and stays an integer.
Why is 0.1 + 0.2 not equal to 0.3 in C++?
double stores numbers in binary, and 0.1, 0.2 and 0.3 can't be represented exactly, so the sum comes out a tiny bit different and 0.1 + 0.2 == 0.3 is false. Compare decimals with a small tolerance instead: abs(a - b) < 1e-9. For money, many programs store whole cents in an integer.
What happens if you divide by zero in C++?
Dividing an integer by zero is undefined behaviour; on Linux the program usually crashes with "Floating point exception". Dividing a double by zero doesn't crash on ordinary hardware: 1.0 / 0.0 gives inf, and 0.0 / 0.0 gives NaN, a special "not a number" value. Either way, check the divisor before dividing.
How do I swap two variables in C++?
Call std::swap(a, b), which works for numbers, strings, vectors and most other types. It's declared in <utility>, which most standard headers include anyway. Writing it by hand needs a third variable: int temp = a; a = b; b = temp;.
How do I get the same random numbers every time I run the program?
Seed the engine with a fixed number instead of random_device: mt19937 gen(42);. The engine then produces the same sequence on every run, which makes bugs easy to reproduce and tests repeatable. The mt19937 sequence itself is fixed by the standard, but a distribution such as uniform_int_distribution may turn it into different numbers on a different compiler.
C++ Operators Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Complete the code so it prints the remainder of 20 divided by 6.
cout << 20 6 << endl;
What does this print?
cout << 11 / 4 << endl;
What does this print?
int x = 10;
x -= 4;
x *= 3;
cout << x << endl;
Which expression gives 2.5?
Why is int big = 2147483647; big++; a problem in C++?
C++ Operators Quiz
5 questions to check what you learned.
Which header provides sqrt and pow?
- <cmath>
- <iostream>
- <string>
- <random>
What does
static_cast<int>(8.9)give?- 9
- 8.9
- An error
- 8
What does
ceil(2.1)return?- 2
- 2.1
- 2.5
- 3
What's the modern C++ way to roll a fair six-sided dice?
- rand() % 6
- random(6)
- uniform_int_distribution<int>(1, 6) with an mt19937 generator
- dice(6)
Why does
cout << 3.0;print3?- By default cout doesn't show trailing zeros
- 3.0 is stored as an int
- cout rounds every number
- It's a compiler bug