sky_full_of_stars's blog

By sky_full_of_stars, history, 4 years ago, In English

I was solving this.

I encountered a problem while using std::accumulate.

I noticed that accumulate(v.begin(), v.end(), 0L) behaves differently in sublimText/Ideone and Codeforces.

for example,

int main() {
vector<long long> v{1,-1000000000,1,-1000000000,1,-1000000000};
long long sum = accumulate(v.begin(), v.end(), 0L);
cout<<sum;
}

in sublimeText or Ideone: prints -2999999997 and in Codeforces prints 1294967299.

you can try running this here

AC solution

Wrong solution

however, when 0L is changed to 0LL in accumulate function, both sublime text and CF returns the right sum (-2999999997)

is this expected? can someone help me understand this weird behavior?

  • Vote: I like it
  • -20
  • Vote: I do not like it

| Write comment?
»
4 years ago, # |
  Vote: I like it 0 Vote: I do not like it

0L= long (32 bits) 0LL= long long(64 bits)

  • »
    »
    4 years ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    yeah! but the question is why does it work in ideone and not on codeforces?

    is there any difference I should be aware of?

    • »
      »
      »
      4 years ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      Probably long is 64-bit on ideone. In c++ types like int or long have no fixed size and are architecture-defined

»
4 years ago, # |
  Vote: I like it +24 Vote: I do not like it

First of all, this has nothing to do with Sublime Text. Sublime Text is a text editor, not a compiler.

Yes, this is expected. 0L is of type long, 0LL is of type long long. In std::accumulate, the return type is the same as the type of the last argument. cppreference even warns of this situation:

If left to type inference, op operates on values of the same type as init which can result in unwanted casting of the iterator elements. For example, std::accumulate(v.begin(), v.end(), 0) likely does not give the result one wishes for when v is std::vector<double>.

In 32-bit GCC, long is a 32-bit data type while long long is a 64-bit data type. You probably used 64-bit GCC where long and long long are both 64 bits. In short, you get this weird value because of an overflow.