javascript - 无符号右移函数不适用于负输入

标签 javascript php bit-manipulation

我正在寻找一种在 64 位版本的 PHP 5.5.14 中使用 JavaScript 中的 >>> 函数的方法。我发现this function在我的谷歌搜索中:

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; 
}

这个函数对于正数似乎工作得很好,但是当传递负数时我得到不同的结果。

例如:

PHP:

In: echo uRShift(-672461345, 25);
Out: -149

JavaScript(Chrome 35):

In: -672461345 >>> 25
Out: 107

编辑:

我还尝试了上面链接的答案中提到的其他功能。

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

PHP:

In: echo uRShift(-672461345, 25);
Out: 549755813867

Runnable

最佳答案

常量0x80000000(在本例中,它被编写为对hexdec的调用,并存储在$z变量中)代表最低符号二进制补码负整数(二进制的100000....)。表达式 ~$z 应给出该值的按位 NOT,即最高符号正整数(最终为 2147483647)。

原始数字( 0x80000000,即2147483648)无法存储为有符号 32位整数,所以通常它会存储为某种类型的 float 。不幸的是,PHP 5.5 认为 ~(2147483648) 等于 -2147483649,如果我们处理的是例如64 位整数。

事实上,在 runnable 中回显 PHP_INT_SIZE 表明整数是 8 个字节,即 64 位。因此,该算术在 PHP 5.5 中无法正常运行。

要解决此问题,只需将 ~$z 替换为静态常量,如下所示:

function uRShift($a, $b) 
{ 
    if ($a < 0) 
    { 
        $a = ($a >> 1); 
        $a &= 2147483647; 
        $a |= 0x40000000; 
        $a = ($a >> ($b - 1)); 
    } else { 
        $a = ($a >> $b); 
    } 
    return $a; 
}

这个功能仍然有一些弱点;例如,移位 0 无法正常工作。

关于javascript - 无符号右移函数不适用于负输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24659911/

相关文章:

c++ - -!(condition) 是从 bool 值(掩码 bool 值)获取全位 vector 的正确方法吗?

javascript - Angularjs:按数组相交排序和过滤

javascript - 为什么这个外部 JavaScript 不加载?

php - 何时将类定义中的变量声明为 NULL 值?

php - .htaccess 删除扩展名不起作用

algorithm - 使用位操作判断一个无符号整数是否可以用 2^n-1 的形式表示

javascript - Firebase 云功能警告 : "Arrow function expected no return value consistent-return"

javascript - 如何从 url 中显示模态内的信息?

php - JS/PHP 日期时间和时区,在特定日期时间到期的用户评论

c - 如何翻转和反转 C 中的 int?