Search code examples
c++algorithmstloverflowaccumulate

Why does std::accumulate generate 705032704 as output instead of the sum of the elements in the vector?


The output is 705032704 instead of 5000000000. Why is that? I thought std::accumulate would compute the sum of the elements in the vector.

#include <vector>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <string>
#include <iterator>
#include <queue>
#include <stack>
#include <numeric>

typedef long long ll;

int main()
{

    std::vector<ll> nums = {1000000000, 1000000000,1000000000,1000000000,1000000000};
    std::cout << std::accumulate(nums.begin(), nums.end(), 0);
    std::cin.ignore();

}

Solution

  • The standard algorithm std::accumulate is declared the following way

    template<class InputIterator, class T>
    T accumulate(InputIterator first, InputIterator last, T init);
    

    So the template parameter T is used as the type of the accumulator.

    In this call

    std::accumulate(nums.begin(), nums.end(), 0)
    

    the deduced type of the parameter T is int because the integer literal 0 has the type int. As a result there is an overflow of the sum stored in the accumulator of the type int.

    You have to use at least the long long integer literal 0ll as

    std::accumulate(nums.begin(), nums.end(), 0ll)

    or maybe it is reasonable to use a double floating literal

    std::accumulate(nums.begin(), nums.end(), 0.0 )
    

    Here is a demonstrative program

    #include <iostream>
    #include <vector>
    #include <iterator>
    #include <numeric>
    
    using ll = long long int;
    
    int main()
    {
        std::vector<ll> nums = {1000000000, 1000000000,1000000000,1000000000,1000000000};
        std::cout << std::accumulate( std::begin( nums ), std::end( nums ), 0ll ) << '\n';
        std::cout << std::accumulate( std::begin( nums ), std::end( nums ), 0.0 ) << '\n';
    }
    

    Its output is

    5000000000
    5e+09