Skip to content

01 Beginner The Hundred

Integer Division Truncates

the average that loses its half

#include <iostream>

int main() {
    int monday = 7, tuesday = 2;   // bugs filed

    double avg = (monday + tuesday) / 2;
    std::cout << "bugs per day: " << avg << "\n";   // 9 / 2 = 4.5... right?

    double share = 1 / 3;   // one bug split three ways
    std::cout << "share:        " << share << "\n";
}

Run it. Both results are doubles — what do they print?

Answer

bugs per day: 4 and share: 0. Neither fraction ever existed.

Why

Both operands of / are int, so the compiler picks integer division, which discards the remainder: 9 / 2 is 4 and 1 / 3 is 0 (truncation is toward zero, so -7 / 2 is -3). The double on the left never gets a vote — the entire right-hand side is evaluated first, in int, and only the finished result is converted, so 4 becomes 4.0 and the missing .5 was gone long before the assignment saw it. The declared type of the destination decides nothing about the arithmetic; the operand types decide everything. Nothing here is illegal or lossy by the language's reckoning, so the compiler stays quiet: neither -Wall -Wextra nor -Wconversion nor -Wfloat-conversion says a word (GCC 11.5 and Clang 18 alike). The same mistake wearing a template is std::accumulate(v.begin(), v.end(), 0) — see entry 23.

The fix

Make one operand floating point, so the division itself happens in double:

double avg = (monday + tuesday) / 2.0;                    // 4.5
double avg = static_cast<double>(monday + tuesday) / 2;   // 4.5, same idea

Casting the result doesn't help — static_cast<double>((monday + tuesday) / 2) is still 4, because the truncation already happened inside the parentheses.

Takeaway: the operand types decide the arithmetic, not the type you assign into.

Try it: g++ -std=c++17 main.cpp -o demo && ./demo

Open in Compiler Explorer ↗ Quiz this entry