Why does the right offset -1 always give -1 in PHP?

I am trying to understand why, if I shift the negative integer -1, I always get -1, for example:

echo -1 >> 64; // -1 echo -1 >> 5; // -1 echo -1 >> 43; // -1 echo -1 >> 1; // -1 

Whatever the second operand of the right shift, -1 remains -1 ... I understand that when you perform the right shift, you actually do this:

x >> y = x / 2^y

But in the case of x equal to -1, if so, then:

-1 >> 3 = -1 / 2^3

Shouldn't this value be -1/8 = -0.125?

Thanks for attention.

+6
php negative-number shift
source share
2 answers

Bitwise shift operators are not divided. They do what they have to do - shift bits. In particular, the right shift operator does the following:

  • for each bit starting on the right, set its value to what is on its left
  • for the leftmost bit that has nothing left, save the current value

For example, if your number

 1011...101 

right shift gives you

 11011...10 

So, the rightmost bit (LSB) is lost, and the leftmost bit (MSB) is duplicated. This is called "sign propagation" because the MSB is used to extract positive (MSB = 0) from negative (MSB = 1) numbers.

Negative numbers are stored as "two additions", that is, in a 32-bit system, -x stored as 2^32-x . So, -1 - 10...00 (32 zeroes) - 1 == 1...1 (32 ones) . If you move 32 in accordance with the above procedure, you will again get 32, i.e. -1 >> whatever will always be -1 .

The difference between the right shift and division by two is that the shift gives the same results for odd and even numbers. Since the rightmost bit is lost when you shift an odd number (which has LSB = 1), the result will be the same as the shift of the next lower even number (the same bit combination, but with LSB = 0). Thus, you do not get halves during the shift, as the dividend is forced to be even. For example,

10 10 = 1010 2 , 10/2 = 5.0 and 10 โ†’ 1 == 5 10 == 101 2sub>

11 10 = 1011 2 , 11/2 = 5.5, but 11 โ†’ 1 == 5 10 == 101 2sub>

If you prefer to think of x >> 1 in terms of division, he first โ€œroundsโ€ x to an even number ( x - abs(x) % 2 ), and then divides this number by two.

For x = -1 this gives you (-1 - abs(-1) % 2)/2 == (-1 - 1)/2 = -2/2 = -1 .

+7
source share

This is the same in all languages โ€‹โ€‹that I know - the bitwise arithmetic shift to the right for -1 will be equal to -1, and, as mentioned above, this operation can only be applied to integers.

-1 is represented in binary form, since all bits are filled with the value 1. For an arithmetic shift to the right, the bits will be shifted to the right, and the most significant bit (on the left) will be filled with the sign of the value, for a negative value they will be 1, and for positive ones - 0. Thus, after the shift, he does -1.

There are other types of bitwise shifts, and for a logical shift to the right, the most significant bit is filled with zero. You can get more information here: http://en.wikipedia.org/wiki/Bitwise_operation#Arithmetic_shift

+2
source share

All Articles