已掉线,重新登录

首页 > 绿虎论坛 > 历史版块 > 编程 > PHP > 讨论/求助

php如何实现无符号右移


『回复列表(25|隐藏机器人聊天)』

20.

@幕后导演,嗯,上述代码仅限64位php使用,所以我的sint32原本是这样的:

function sint32($int) {
    if (PHP_INT_MAX == 0x7fffffff) {
        throw new Exception('32位PHP不支持64位整数');
    }
    return unpack('l', pack("L", $int))[1];
}

不过后来我发现它在32位里没有副作用,只是个空操作,所以把抛出异常删了。

但是这个无符号右移函数在32位里确实不能达到预期目的,因为负数在32位里& 0xffffffff后依然是负数,并不会消除它的符号位。

function shr32($x, $bits) {
    if (PHP_INT_MAX == 0x7fffffff) {
        throw new Exception('32位PHP不支持64位整数');
    }
    return ($x & 0xffffffff) >> $bits;
}
(/@Ta/2021-08-23 08:22//)

21.

@幕后导演,我最初给的那个右移函数(网上找的)在32位里应该也是对的。然后我的sint32操作在32位里应该也没有副作用(32位php中的所有整数都是32位有符号整数,所以该函数相当于空操作)。所以用这两个函数应该可以写出32位64位结果一致的代码。

// 32位无符号右移
function shr32($x, $bits) {
    $c = 0x7fffffff >> ($bits - 1);
    return $c & ($x >> $bits);
}

// 转为32位有符号整数
function sint32($int) {
    return unpack('l', pack("L", $int))[1];
}
(/@Ta/2021-08-23 08:16//)

22.

这样之所以可以,是因为负数右移时不是在前面补0,而是在前面补1,所以只要把多余的1去掉,结果就是正确的了。

// 32位无符号右移
function shr32($x, $bits) {
    $c = 0x7fffffff >> ($bits - 1);
    return $c & ($x >> $bits);
}

以下是64位结果,32位也一样,只是前面少了32个1。

php > var_dump(decbin(-2147483647));
string(64) "1111111111111111111111111111111110000000000000000000000000000001"
php > var_dump(decbin(-2147483647 >> 3));
string(64) "1111111111111111111111111111111111110000000000000000000000000000"
(/@Ta/2021-08-23 08:50//)

24.
// 无符号右移>>>
function uright($a, $n) {
    // console.log($a);
    if ($n != 0) {
        $c = 2147483647 >> ($n - 1);
        return $c &($a >> $n);
    } else {
        if (is_string($a)) {
            if (PHP_INT_MAX > 2147483647) {
                $a = intval($a);
            } else {
                $a = floatval($a);
            } 
        } 
        if (!is_int($a)) {
            $a = intval($a);
        } 
        if ((0 > $a) || ($a > 4294967295)) {
            $a &= 4294967295;
            if (0 > $a) {
                $a = sprintf('%u', $a);
            } 
        } 
        return $a;
    } 
}
(/@Ta/2021-09-03 18:16//)

25.

@卷心菜,这是整数运算逻辑,在任何编程语言中都可以实现。这些逻辑最常见的用途是数据加密或者数字签名。

(/@Ta/2021-09-03 18:22//)

26. @老虎会游泳,老虎见多识广
(/@Ta/2021-09-04 03:51//)

上一页 2/2页,共25楼

回复需要登录

8月19日 21:03 星期二

本站由hu60wap6驱动

备案号: 京ICP备18041936号-1