Reputation: 771
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
Upvotes: 4
Views: 86
Reputation: 206727
In both your samples, assuming 32bit int
s, 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 number
is a signed int
, 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 0x80000000
as a binary representation. This happens to be the two's complement representation of INT_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 is 2^31-1
. MIN_INT * -1
would be 2^31
(if it was representable). And guess what representation that would have? 0x80000000
. Back to where you started!
Upvotes: 4