Блог пользователя sky_full_of_stars

Автор sky_full_of_stars, история, 4 года назад, По-английски

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?

  • Проголосовать: нравится
  • -20
  • Проголосовать: не нравится

»
4 года назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

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

  • »
    »
    4 года назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    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 года назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

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

»
4 года назад, # |
  Проголосовать: нравится +24 Проголосовать: не нравится

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.