Skip to content

23 Beginner The Hundred

The Sum That Rounds Every Step

four quarters that don't make a whole

#include <iostream>
#include <numeric>
#include <vector>

int main() {
    std::vector<double> v{0.25, 0.25, 0.25, 0.25};

    std::cout << std::accumulate(v.begin(), v.end(), 0) << '\n';
    std::cout << std::accumulate(v.begin(), v.end(), 0.0) << '\n';
}

Run it. Both lines sum the same four quarters — what do they print?

Answer

0, then 1. The first sum comes out to exactly nothing.

Why

The third argument of std::accumulate is not just a starting value — its type becomes the type of the accumulator. The literal 0 is an int, so the running sum is an int, no matter what the iterators point at. Each step computes acc = acc + 0.25: the addition yields a double (0.25), but storing it back into the int accumulator truncates it to 0 — the sum rounds toward zero at every single step, and four quarters make nothing. The same trap bites integers, too: summing a vector<long long> of large values with init 0 does each addition in long long but stores the result back into the int accumulator, silently narrowing out-of-range sums (implementation-defined until C++20, wrap-around modulo 2^N since) — the total is quietly wrong either way. Worst of all, the compiler is silent — not even -Wconversion flags it, because the narrowing happens inside the <numeric> template, in a system header where GCC suppresses warnings.

The fix

Spell the initial value as the type you want the sum to have:

std::accumulate(v.begin(), v.end(), 0.0);     // accumulates in double → prints 1

std::vector<long long> big{3'000'000'000, 3'000'000'000};
std::accumulate(big.begin(), big.end(), 0LL); // accumulates in long long → 6000000000
                                              // (with 0, an int accumulator wraps it)

Takeaway: std::accumulate sums in the type of its initial value — write the init literal as the type you want (0.0, 0LL), never a reflexive 0.

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

Open in Compiler Explorer ↗ Quiz this entry