Search code examples
c++for-loopreduce

Overflow summing elements in a for loop, but std::reduce works


I was doing a comparison when summing elements of a vector using for loop and std::reduce, but the loop leads to an overflow, and I am struggling to find out why.

Here is the code:

void red(std::vector<unsigned> &v){
    std::cout << std::reduce(v.begin(), v.end(), 0) << std::endl;
}

void sum(std::vector<unsigned> &v){
    unsigned long long s = 0;
    for (auto i : v)
        s += i;
    std::cout << s << std::endl;
}

Calling the functions:

std::vector<unsigned> v(std::stoi(argv[1]));
std::iota(v.begin(), v.end(), 0);
sum(v);
red(v);

I expected the same result in both cases, but for some big values the loop generate strange results.

Up to 10000 both gives the same (right) value.

For 100000, "red" prints the right value, but "sum" prints 704982704.

I even tried to do:

void red(std::vector<unsigned> &v){
    unsigned long long s = std::reduce(v.begin(), v.end(), 0);
    std::cout << s << std::endl;
}

But nothing changes.


Solution

  • You've got it backward: your loop code (sum()) gives the right answers, but your use of std::reduce() is broken and so (red()) gives wrong answers.

    Try it for 69999:

     2449895001 (sum())
    -1845072295 (red())
    

    This happens because you passed a signed integer 0 to std::reduce(). You should pass an unsigned one instead, such as 0uLL.