In C, following C99 rules since long long did not come out until then:
2147483648 is not a 32-bit int. It is a 64-bit integer as 2147483648 is not in the int32_t positive range.
-2147483648 is not a 32-bit int. It is a 64-bit integer as 2147483648 is not in the int32_t positive range either, the - is applied after the constant type is formed.
The expected math output is the sum with 64-bit math.
int main(void) {
long long a = 2147483648 + 2147483648;
printf("%lld\n", a);
a = 2147483648 + 2147483648 + 2147483648;
printf("%lld\n", a);
return 0;
}
Output
4294967296
6442450944
OP reports:
Well, the output for me is 0 and 2147483648 when I copied your code.
OP is perhaps using a C89 compiler with long long extensions. visual-studio-2019 is not fully C99 compliant. Example Does Visual Studio 2017 fully support C99?.
In that case:
C89 uses different rules e.g.:
2147483648 is not a 32-bit int. It is a 32-bit unsigned long
2147483648 + 2147483648 is unsigned overflow and well defined to sum to 0.
2147483648 + 2147483648 + 2147483648, as 32-bit unsigned long math is a 32-bit unsigned long 2147483648.
Assigning 32-bit unsigned long 2147483648 to a long long is the same value, different type.
Moral of the story: Consider starting computation with the desired end type.
With the below code, the type on the left does not influence the addition on the right. This is the same problem as Why (not) write 1,000,000,000 as 1000*1000*1000?
long long a = 2147483648 + 2147483648 + 2147483648;
Alternatives:
long long a = (long long) 2147483648 + 2147483648 + 2147483648;
long long a = 0LL + 2147483648 + 2147483648 + 2147483648;
long long a = 2147483648;
a += 2147483648;
a += 2147483648;