Though the two snippets below have a slight difference in the manipulation of the find variable, still the output seems to be the same. Why so?
First Snippet
#include<iostream>
using namespace std;
int main()
{
int number = 3,find;
find = number << 31;
find *= -1;
cout << find;
return 0;
}
Second Snippet
#include<iostream>
using namespace std;
int main()
{
int number = 3,find;
find = number << 31;
find *= 1;
cout << find;
return 0;
}
Output for both snippets:
-2147483648
In both your samples, assuming 32bit
ints, you’re invoking undefined behavior as pointed out in Why does left shift operation invoke Undefined Behaviour when the left side operand has negative value?Why? Because
numberis a signedint, with 32bits of storage.(3<<31)is not representable in that type.Once you’re in undefined behavior territory, the compiler can do as it pleases.
(You can’t rely on any of the following because it is UB – this is just an observation of what your compiler appears to be doing).
In this case it looks like the compiler is doing the right shift, resulting in
0x80000000as a binary representation. This happens to be the two’s complement representation ofINT_MIN. So the second snippet is not surprising.Why does the first one output the same thing? In two’s complement, MIN_INT would be
-2^31. But the max value is2^31-1.MIN_INT * -1would be2^31(if it was representable). And guess what representation that would have?0x80000000. Back to where you started!