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