PHP 无符号右移 - 故障问题

6

因此,在使用我的方法在PHP中执行无符号右移操作(>>>)时,当数字涉及负数时,结果是不正确的。

PHP应用程序结果:

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

JAVA应用程序结果:

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

顶部的结果是正确的,由Java生成,底部的结果是不正确的,由PHP生成。

只有在PHP中数字为负数时,它才会失败。

这些应用程序中使用的移位是:

如果可以,请帮助!

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;

好的,你的结果与代码之间的对应关系不太清楚。你能否创建一个最小化测试用例,清晰地演示输入和输出的使用方式? - Oliver Charlesworth
我修复了它,所以现在很清楚他的输入和输出是什么。 - Mitchell M
2个回答

13

这个 uRShift 更加简短,正确地处理32位和64位 PHP,并且在32位PHP中与Java版本给出相同的结果,因为它具有与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

以下示例中的移位不起作用:-672461345 >>> 25。根据JS,它应该是107,但它返回549755813867。我已经搜索了您的代码,并在几个开源项目中找到了它,我即将使用它,所以澄清事情是很好的。 更多信息请参见:http://stackoverflow.com/questions/24659911/unsigned-right-shift-function-not-working-for-negative-input - frzsombor
注意!如果你正在寻找一个能够输出与 JavaScript 相同结果的 PHP 函数,我终于找到了一个可行的解决方案!更多细节、实时演示、测试和示例请参考:https://dev59.com/-p3ha4cB1Zd3GeqPS1Uw#43359819。 - frzsombor

3

试试这个函数而不是之前的。

function uRShift($a, $b) 
{ 
    $z = hexdec(80000000); 
    if ($z & $a) 
    { 
        $a = ($a >> 1); 
        $a &= (~$z); 
        $a |= 0x40000000; 
        $a = ($a >> ($b - 1)); 
    } else { 
        $a = ($a >> $b); 
    } 
    return $a; 
}  

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接