Skip to content
Theory · Operators and Expressions · lesson 1 of 8

Arithmetic: integer division, remainder, overflow

What you'll learn

What you'll learn:

  • predict the result of / and % on integers, negative ones included;
  • check conditions with comparisons and the &&, ||, ! operators;
  • read, set and clear a single bit in an unsigned number;
  • add parentheses where operator precedence changes what an expression means.
Five plates of three apples under a board 17 / 5, and a basket with the two leftover apples tagged 17 % 5

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.

C++
#include <iostream>

int main() {
    int apples = 17;
    int kids = 5;
    std::cout << apples / kids << '\n';  // 3
    std::cout << apples % kids << '\n';  // 2
}

Picture seventeen apples shared equally onto five plates, one for each kid. Each plate gets three apples, and two stay in the basket. The / operator produced the quotient, how many apples sit on one plate, and % produced the remainder, that is what is left in the basket.

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. The fractional part is discarded for a negative result too: -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:

C++
std::cout << -17 / 5 << ' ' << -17 % 5 << '\n';  // -3 -2
std::cout << 17 / -5 << ' ' << 17 % -5 << '\n';  // -3 2

The 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, these are the numbers 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. A mechanical car odometer works the same way: after its last number it shows all zeros again.

C++
#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. Adding one to the maximum crossed the boundary upward, like the odometer. Subtracting from zero crossed it downward, which an odometer cannot do.

Common mistake

The result of dividing two int values is stored in a double variable in the hope of getting a fraction:

C++
#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.

Key points

  • Dividing two integers discards the fractional part: 17 / 5 is 3, and -17 / 5 is -3.
  • % gives the remainder, and the remainder takes the sign of the left operand.
  • Overflowing an int is undefined behavior, while an unsigned wraps around.
  • Only a division with at least one double operand gives a fraction.

Subscribe to take the course

The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.

Sign in another way