Arithmetic: integer division, remainder, overflow
The operators +, - and * work on whole numbers the same way school arithmetic does. Division is different: when both numbers are int, the result is an int too, and an int has no fractional part.
#include <iostream>
int main() {
int apples = 17;
int kids = 5;
std::cout << apples / kids << '\n'; // 3
std::cout << apples % kids << '\n'; // 2
}Seventeen apples shared among five kids give three each, with two apples left over. The / operator produced the quotient, and % produced the remainder.
Integer division
The values an operator works on are called operands. Dividing two integer operands is integer division: the fractional part of the result is discarded, not rounded. So 19 / 5 is also 3, even though 3.8 is closer to four. A negative result is rounded toward zero as well: -17 / 5 is -3, not -4.
If either operand is a double, the other is converted to double, and the division keeps the fraction: 17 / 5.0 is 3.4. Integer division by 0 is undefined behavior: the standard does not say what happens then.
Remainder
The % operator works only on integer operands. The quotient and the remainder are linked: a / b * b + a % b equals a. That is why the remainder takes the sign of the dividend, the left operand:
std::cout << -17 / 5 << ' ' << -17 % 5 << '\n'; // -3 -2
std::cout << 17 / -5 << ' ' << 17 % -5 << '\n'; // -3 2The remainder helps take a number apart into digits: n % 10 is the last digit, and n / 10 is the number without it. For 253, these are 3 and 25.
Overflow
An int holds numbers from a limited range: where it takes 4 bytes, from -2147483648 to 2147483647. If the result of +, - or * does not fit in this range, an overflow occurs. For int and long long, this is undefined behavior too.
The unsigned type unsigned (full name unsigned int) holds only non-negative numbers. A literal with the u suffix, such as 5u, has type unsigned. For this type, crossing the boundary is well defined: the arithmetic wraps around, and 0 comes again after the maximum.
#include <iostream>
int main() {
unsigned zero = 0u;
std::cout << zero - 1u << '\n'; // 4294967295
std::cout << zero - 1u + 1u << '\n'; // 0
}The number 4294967295 is the maximum of a 4-byte unsigned. Subtracting from zero crossed the boundary downward, and adding one to the maximum crossed it upward.
Common mistake
The result of dividing two int values is stored in a double variable in the hope of getting a fraction:
#include <iostream>
int main() {
double half = 5 / 2; // ✗
std::cout << half << '\n'; // 2
}The compiler sees no error, and the program prints 2. First 5 / 2 runs as integer division, and only its result 2 becomes a double. The type of the variable on the left does not affect the division: the operand types do. Write 5 / 2.0, and half gets 2.5.