I am new to bit manipulations tricks and I wrote a simple code to see the output of doing single bit shifts on a single number viz. 2
#include <iostream>
int main(int argc, char *argv[])
{
int num=2;
do
{
std::cout<<num<<std::endl;
num=num<<1;//Left shift by 1 bit.
} while (num!=0);
return 0;
}
The output of this is the following.
2
4
8
16
32
64
128
256
512
1024
2048
4096
8192
16384
32768
65536
131072
262144
524288
1048576
2097152
4194304
8388608
16777216
33554432
67108864
134217728
268435456
536870912
1073741824
-2147483648
Obviously, continuously bit shifting to the left by 1 bit, will result in zero as it has done above, but why does the computer output a negative number at the very end before terminating the loop (since num turned zero)??
However when I replace int num=2
by unsigned int num=2
then I get the same output except
that the last number is this time displayed as positive i.e. 2147483648
instead of -2147483648
I am using the gcc
compiler on Ubuntu Linux
For signed numbers, the sign bit is used to fill the vacated bit positions. In other words, if the number is positive, 0 is used, and if the number is negative, 1 is used. The result of a right-shift of a signed negative number is implementation-dependent.
A bit-shift moves each digit in a number's binary representation left or right. Within right-shifts, there are two further divisions: logical right-shift and arithmetic right-shift. A left-shift is represented by the << operator, while a right-shift is represented by the >> operator.
The left shift and right shift operators should not be used for negative numbers. The result of is undefined behaviour if any of the operands is a negative number. For example results of both 1 >> -1 and 1 << -1 is undefined. If the number is shifted more than the size of integer, the behaviour is undefined.
A negative value indicates a shift to the right, and a positive value indicates a shift to the left. A vertical shift is a change in the y-intercept, or b-value.
That's because int
is a signed integer. In the two's-complement representation, the sign of the integer is determined by the upper-most bit.
Once you have shifted the 1 into the highest (sign) bit, it flips negative.
When you use unsigned
, there's no sign bit.
0x80000000 = -2147483648 for a signed 32-bit integer.
0x80000000 = 2147483648 for an unsigned 32-bit integer.
EDIT :
Note that strictly speaking, signed integer overflow is undefined behavior in C/C++. The behavior of GCC in this aspect is not completely consistent:
num = num << 1;
or num <<= 1;
usually behaves as described above.num += num;
or num *= 2;
may actually go into an infinite loop on GCC.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With