Why 7 / 2 equals 3 in C++ (integer division)

Short answer: when both operands are integers, C++ does integer division — the fractional part is thrown away, not rounded. 7 / 2 is 3, -7 / 2 is -3 (truncated toward zero), and 7 % 2 gives the remainder, 1.

This surprises almost everyone coming from a calculator mindset, and it's the source of a huge share of beginner bugs — broken averages, always-zero percentages, wrong loop counts. Run this and read every line:

#include <iostream>
using namespace std;

int main() {
    cout << "7 / 2       = " << 7 / 2 << endl;        // 3   (fraction dropped)
    cout << "7 % 2       = " << 7 % 2 << endl;        // 1   (remainder)
    cout << "7.0 / 2     = " << 7.0 / 2 << endl;      // 3.5 (one operand is double)
    int a = 7, b = 2;
    cout << "(double)a/b = " << (double)a / b << endl; // 3.5 (cast first!)
    cout << "(double)(a/b) = " << (double)(a / b) << endl; // 3 (too late: divided as ints)
    return 0;
}

The rule, precisely

The type of a / b is decided before the division runs, from the operand types:

The last two lines of the demo above are the interview-grade detail: (double)a / b fixes the problem (cast happens before the division), while (double)(a / b) casts an already-truncated 3 — the parentheses decide everything.

The modern way to write the cast

C-style casts (double)a work but are blunt. C++'s preferred form says exactly what's happening:

double exact = static_cast<double>(a) / b;   // 3.5

Same result, but searchable, and it won't accidentally compile when you meant something else. (Our in-browser playground covers the teaching core and doesn't support static_cast yet — try it on your desktop compiler.)

Negative numbers: truncate toward zero, not "round down"

This is where languages disagree, and it's a fantastic interview point. C++ truncates toward zero:

-7 / 2   // -3  (toward zero; Python would give -4)
7 / -2   // -3
-7 % 2   // -1  (remainder keeps the dividend's sign)

C++ truncation: the result is the integer part with the sign applied. Python, by contrast, floors toward negative infinity — same math, different convention. If you're porting code between languages, this bites.

The three bugs this causes in real code

  1. The always-zero average: sum / count with both ints gives 0 whenever count > sum. Fix: static_cast<double>(sum) / count.
  2. The always-zero percentage: x / total * 100 — the division happens first and truncates. Fix: 100.0 * x / total (multiply first) or cast.
  3. The loop that runs one time too few/many: for (int i = 0; i <= n; i += n/2) style arithmetic — with odd n, integer division changes the step. Same family as the off-by-one bugs in loops.

Want to round instead of truncate?

Integer division can't round, but you can make it: add half the divisor before dividing (for positive numbers), or cast, add 0.5, and cast back:

int rounded = (a + b / 2) / b;        // e.g. 7/2 -> (7+1)/2 = 4
int rounded2 = (int)(7.0 / 2 + 0.5);  // 4

For serious numeric code, reach for std::round from <cmath> instead of hand tricks.

Interview questions on this theme

  1. "What's 7 / 2 and 7 % 2?" — 3 and 1; then they'll ask about negatives (above).
  2. "Why is 100.0 * x / total different from x / total * 100?" — evaluation order; the first never divides two ints.
  3. "Can you use % on doubles?" — no, only integers (use fmod from <cmath> for floating point).
  4. "What's i % 2 used for?" — even/odd checks, which is exactly the continue trick in our loops guide.

Practice in the playground

  1. Change the demo to a = 100, b = 7 and predict all five outputs before running.
  2. Compute the average of 1, 2 the wrong way, then the right way, and compare.
  3. Print whether each number 1–20 is even or odd using % (loops + division in one exercise).

Related: for vs while loops, beginner interview questions, and the Hello World lesson if you're just starting.