PHP’s bitwise operators `<<`

and `>>`

implement Arithmetic Bit Shifting. This means:

- Left shift (using
`<<`

operator) fills in zero(s) on the right end of the bitfield, and bit(s) shifted off the left end are discarded; - Right shift (using
`>>`

operator) discards bit(s) shifted off the right end of the bitfield and copy(ies) of sign bit are shifted in on the left end.

Logical Bit Shifting is different in that on right shifts, zeros are shifted in on the left end of the bitfield, affecting the sign of negative integer.

On 32 bit platforms, `-2147483648`

is the largest negative integer. Binary representation of this integer gives only the Most Significant Bit `ON`

and all other bits are `OFF`

. Shifting bits of this number `$n`

steps to the right would actually shift in `$n`

copies of the Most Significant Bit (or Sign Bit) and discard the same number of bits from the right.

1 2 3 4 5 |
$n = 30 echo decbin( -2147483648 ); // 10000000000000000000000000000000 //Arithmetic Right Shift echo decbin( -2147483648 >> $n ); // 11111111111111111111111111111110 |

The same is stated by PHP manual:

Bit shifting in PHP is arithmetic. Bits shifted off either end are discarded. Left shifts have zeros shifted in on the right while the sign bit is shifted out on the left, meaning the sign of an operand is not preserved. Right shifts have copies of the sign bit shifted in on the left, meaning the sign of an operand is preserved – PHP manual

### Why Logical Right Shifting in PHP?

In php, bitwise operators are commonly used for manipulating colors, working with user permission management, character encoding/decoding etc and logical right shift is sometimes much needed to simplify operations. Many recommend its addition to php’s core and someone has even put up a request for comment for a new operator. No new operator is needed for Logical Left Shifts because logical and arithmetic left shift are the same.

Implementing logical right sift in PHP:

1 2 3 4 |
function logical_right_shift( $int , $shft ) { return ( $int >> $shft ) //Arithmetic right shift & ( PHP_INT_MAX >> ( $shft - 1 ) ); //Deleting unnecessary bits } |

This function does not validate input. You have to make sure that both of the arguments `$int`

and `$shft`

are integer. Inappropriate arguments may cause unexpected results.

### Tests

I have tested `logical_right_shift`

on 32 bit platform, specially with key cases:

`0`

where all 32 bits are`OFF`

;`~ 0`

or`-1`

where all 32 bits are`ON`

;`PHP_INT_MAX`

– a positive integer with 31 bits`ON`

and just the sign bit`OFF`

, and;`~ PHP_INT_MAX`

– a negative integer (sign bit`ON`

) with 31 bits`OFF`

.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
//Tested With $int = 0 ; //0, -1, PHP_INT_MAX, ~PHP_INT_MAX $shift = 5; echo 'INT: '.$int ."\n"; echo 'Before: '.substr(str_repeat('0',32).decbin($int),-32)."\n"; echo 'After: '.substr(str_repeat('0',32).decbin(logical_right_shift($int,$shift)),-32); //INT: 0 //Before: 00000000000000000000000000000000 //After: 00000000000000000000000000000000 //INT: -1 //Before: 11111111111111111111111111111111 //After: 00000111111111111111111111111111 //INT: 2147483647 //PHP_INT_MAX //Before: 01111111111111111111111111111111 //After: 00000011111111111111111111111111 //INT: -2147483648 //~ PHP_INT_MAX //Before: 10000000000000000000000000000000 //After: 00000100000000000000000000000000 |

### Notes

`logical_right_shift()`

was tested to work fine with integers on 32 and 64 bit platforms. It should also work with strings (not tested).- Bitwise operators are high performance operators, often faster than arithmetic ones. You should not expect that high performance when using
`logical_right_shift()`

. - The function uses
`PHP_INT_MAX`

that is available since PHP 5.0.5.