问题
How do you get number like -10
from these bit shifting practice problems?
From what I understand X*32
can be written as x<<5
. But how are you to get numbers like x*66
, or X*(-10)
?
回答1:
General Explanation
Bit shifting is primarily aimed to shift the binary representation of a number. It is not for multiplication.
23 = 0001 0111
23 << 1 = 0001 0111 << 1 = 0010 1110 = 46
However, as the binary representation of a number is changed, the number it represents is also changed. This is just how computer binary system works. And thus people sometimes exploit this behavior as a "hack", mostly to speed up the computation time.
Let's try to understand it more:
Left bit-shift and right bit-shift
Now, when the number represented is of integer
type, then shifting the binary representation of a number by 1 to the left will be equivalent to multiplying it by 2:
23 = 0001 0111
23 << 1 = 0001 0111 << 1 = 0010 1110 = 46 //left bit-shift by 1, number becomes doubled
Given that there is no overflow for the given data type:
255 = 1111 1111 //assuming 8-bit data type
255 << 1 = 1111 1111 << 1 = 1111 1110 = 254 //not multiplied by 2, because of overflow
While shifting integer number to the right will be equivalent as dividing it by 2 and then rounding it down:
23 = 0001 0111
23 >> 1 = 0001 0111 >> 1 = 000 1011 = 11 //right bit-shift by 1, number becomes halved, rounded down
Some use and link to multiplication and division
Since bit-shifting operation is typically less costly than multiplication, to speed things up, you will see in some program, people use left bit-shift operation (as a replacement of multiplication) when they mean to multiply it by an integer number of power of 2
(that is 2, 4, 8, 16, etc):
int a = 23;
...
a = a << 2; //=102; multiply by 4, equivalent to a = a * 4, but faster operation
Or use right bit-shift operation (as a replacement of division and rounding down) to divide it with an integer number of power of 2
(that is 2, 4, 8, 16, etc)
int a = 23;
...
a = a >> 2; //=5; divide by 4 and rounding down, equivalent to integer division a = a / 4, but faster
Concluding remarks
Note that only if you operate with number with power of 2, all the multiplications and divisions above can be replaced by left bit-shift or right bit-shift.
In your example, 66 and -10 are not integer number which of power of 2, thus you cannot "hack" the multiplication/division with binary-shifting operation.
In general, use bit-shift operation if you mean for bit-shifting, as bit-shifting has many other uses than just "hacking" for multiplication/division with integer number of power of 2. If you want to multiply or divide, be happy with just using multiplication (*
) or division (/
) operator.
Some additional remarks:
That being said, I would just like to add some more things regarding the bit-shift for further explanation (it won't do harm):
- signed
integer
type can hold positive or negative number - there is a difference between logical bit-shift and arithmetic bit-shift when dealing with negative number. One will give
0
in the emptied-space after shift while the other will give1
- Hence, it probably best to note that the bit-shift is mainly used for
unsigned
type, such like for creating bit-masks by bit shifting. That is,unsigned
is recommended to be used to avoid sign-extension surprises when you deal with negative number (right) bit-shift.
来源:https://stackoverflow.com/questions/35762313/bit-shifting-x-a-number