Search code examples
phpnegative-numberbit-shift

PHP Unsigned Right Shift - Malfunctioning


So, when using my method to preform a ( >>> ) unsigned right shift in PHP, the result is incorrect when the numbers involve negatives.

PHP Application Results:

INPUT: 10 >>> 3
INPUT: -10 >>> 3
OUTPUT: 1
OUTPUT: 2684354558

JAVA APPLICATION RESULTS:

INPUT: 10 >>> 3
INPUT: -10 >>> 3
OUTPUT: 1
OUTPUT: 536870910

(The top results are correct and generated by Java and then the bottom results are incorrect and generated by PHP)

It's only when the number is negative in PHP that it fails.

The shifts being used in those applications is:

Please help if you can!

Method for shifting in PHP:

function urshift($x, $n){
$mask = 0x40000000;
if ($x < 0){
    $x &= 0x7FFFFFFF;
    $mask = $mask >> ($n-1);
    $ret = ($x >> $n) | $mask;
    $ret = str_pad(decbin($ret), 32, '0', STR_PAD_LEFT);
    $ret[0] = '1';
    $ret = bindec($ret);
} else {
        $ret = (int)$x >> (int)$n;
}
return $ret;

Solution

  • This uRShift is shorter, works correctly with 32- and 64-bit PHP and gives the same result as the Java version on 32-bit PHP which has same size ints as Java;

    function uRShift($a, $b)
    {
        if($b == 0) return $a;
        return ($a >> $b) & ~(1<<(8*PHP_INT_SIZE-1)>>($b-1));
    }
    
    > uRShift(-10,3)  
    536870910
    
    > uRShift(10,3)
    1