Why doesn't this code print same number? :
long long a, b;
a = 2147483647 + 1;
b = 2147483648;
printf("%lld\n", a);
printf("%lld\n", b);
I know that int variable's maximum number is 2147483647 because int variable is 4 byte. But as I know, long long variable is 8 byte, but why does that code act like that?
2147483647 + 1 is evaluated as the sum of two ints and therefore overflows.
2147483648 is too big to fit in an int and is therefore assumed by the compiler to be a long (or a long long in MSVC). It therefore does not overflow.
To perform the summation as a long long use the appropriate constant suffix, i.e.
a = 2147483647LL + 1;
Because range of int in C/C++ is -2147483648 to +2147483647.
So when you add 1, it overflows the max limit of int.
For better understanding, assume the whole range of int puts on a circle in proper order:
2147483647 + 1 == -2147483648
2147483647 + 2 == -2147483647
If you want to overcome this, try to use long long instead of int.
Nice question. As others said, numbers by default are int, so your operation for a acts on two ints and overflows. I tried to reproduce this, and extend a bit to cast the number into long long variable and then add the 1 to it, as the c example below:
$ cat test.c
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
void main() {
long long a, b, c;
a = 2147483647 + 1;
b = 2147483648;
c = 2147483647;
c = c + 1;
printf("%lld\n", a);
printf("%lld\n", b);
printf("%lld\n", c);
}
The compiler does warn about overflow BTW, and normally you should compile production code with -Werror -Wall to avoid mishaps like this:
$ gcc -m64 test.c -o test
test.c: In function 'main':
test.c:8:16: warning: integer overflow in expression [-Woverflow]
a = 2147483647 + 1;
^
Finally, the test results are as expected (int overflow in first case, long long int's in second and third):
$ ./test
-2147483648
2147483648
2147483648
Another gcc version warns even further:
test.c: In function ‘main’:
test.c:8:16: warning: integer overflow in expression [-Woverflow]
a = 2147483647 + 1;
^
test.c:9:1: warning: this decimal constant is unsigned only in ISO C90
b = 2147483648;
^
Note also that technically int and long and variations of that are architecture-dependent, so their bit length can vary.
For predictably sized types you can be better off with int64_t, uint32_t and so on that are commonly defined in modern compilers and system headers, so whatever bitness your application is built for, the data types remain predictable. Note also the printing and scanning of such values is compounded by macros like PRIu64 etc.