当前位置: 首页 > 面试题库 >

PHP中的无符号右移/零填充右移/ >>>(等效于Java / JavaScript)

阙阳夏
2023-03-14
问题内容

在将其标记为重复项之前,请阅读以下内容,并检查 我的代码 * 我更新的代码!



所以我的问题是,我必须实现Java / JavaScript’>>>’(无符号右移/零填充右移),但是我无法以完全相同的方式工作。

我选择了在SO和Web上找到的11个最有前途的实现(链接在代码中作为注释添加),并添加了一些测试用例。不幸的是 功能返回的Java /
JS相同响应的测试ALL。 (也许其中一些仅在32位系统上运行)

实时代码+ JS + PHP结果演示(单击运行):
http :
//phpfiddle.org/main/code/bcv7-bs2q
*
http://phpfiddle.org/main/code/dpkw-
rxfe

最接近的功能是:

// http://stackoverflow.com/a/27263298
function shr9($a,$b) { 
    if($a>=0) return $a>>$b;
    if($b==0) return (($a>>1)&0x7fffffff)*2+(($a>>$b)&1);
    return ((~$a)>>$b)^(0x7fffffff>>($b-1)); 
}

// http://stackoverflow.com/a/25467712
function shr11($a, $b) { 
    if ($b > 32 || $b < -32) {
        $m = (int)($b/32);
        $b = $b-($m*32);
    }

    if ($b < 0)
        $b = 32 + $b;

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

不幸的是,shr9在 (-10 >>> -3)和 (32 >> 32)上失败,但是是 唯一* 通过(-3 >>>
0)的代码;并且shr11在(-3 >>> 0)和(32 >>> 32)上均失败。

测试用例:

         0 >>> 3    == 0 
         3 >>> 0    == 3 
         0 >>> -3   == 0 
        -3 >>> 0    == 4294967293 (in JS); -3 (in Java)  
        10 >>> 3    == 1 
        10 >>> -3   == 0 
       -10 >>> 3    == 536870910 
       -10 >>> -3   == 7 
-672461345 >>> 25   == 107 
        32 >>> 32   == 32 
       128 >>> 128  == 128

编辑:我发现仅在JavaScript中-3 >>> 0等于 (为什么?)
,但在Java中等于。不幸的是,这并不能改变我仍然无法获得任何函数通过所有测试的事实。4294967293 __-3

*大更新:

从PHP 7开始,移位负数被认为是无效的,并导致:“ 致命错误:未捕获的ArithmeticError:移位负数
”。据此,我认为我们不必通过那些测试,因此我已经更新了问题和代码。


问题答案:

在研究了问题的两个函数(“ shr9”和“
shr11”)并合并/调整了好部分之后,我终于找到了解决方案。所有测试都通过了(我什至在演示中添加了更多内容),它也适用于负数班次。

[现场演示]

function unsignedRightShift($a, $b) {
    if ($b >= 32 || $b < -32) {
        $m = (int)($b/32);
        $b = $b-($m*32);
    }

    if ($b < 0) {
        $b = 32 + $b;
    }

    if ($b == 0) {
        return (($a>>1)&0x7fffffff)*2+(($a>>$b)&1);
    }

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

代码不仅准确,而且速度也很快。
基准测试结果:100000次循环:0.25秒
基准测试:http :
//phpfiddle.org/main/code/mj68-1s7e



 类似资料:
  • 在我的系统中,在二进制(十进制255)中是(预期是8位字符)1111 1111。 类似地,如预期的0111 1111。左边填满了一个零。 是预期的1000 0000。 例如,现在我想生成未签名的字符0010 0000。 我尝试了,但输出1110 0000....怎么了?为什么左边突然被一个塞满了? 如何生成启用第N位(从左侧开始)的? 我想 此刻,正在给我 对于、存在此问题,但对于或更高版本不再发

  • 简单的问题:为什么如果我在Java中对字节变量应用无符号右移(也是短的),它就像int一样威胁它: 控制台输出:

  • 抱歉,如果这个问题已经提出,我已经做了深入的搜索,什么都没有。 现在,我知道: 会在左边用0填充我的价格,所以25的价格会导致00025 如果我想把它们垫在右边,结果是25000呢?如何仅使用String.format模式?

  • 问题内容: 无符号右移运算符在最左边插入0。所以当我这样做 输出 因此,它将在最左边的位中插入0。 输出 不应该是0吗? 问题答案: 参见http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.19 如果左侧操作数的提升类型为int,则仅将右侧操作数的最低5位用作移位距离。就像右侧操作数受到掩码值0x1f(0b1111

  • 问题内容: 我试图在Java代码中用php(来自Java语言的DataOutputStream)实现php中的DataOutputStream,它们会像这样>> 在PHP中,我只能像这样>> 我如何在php中做到这一点? 谢谢 问题答案: 您可以使用带符号的移位运算符来实现无符号的右移位运算符的行为,如下所示: 的值是零扩展的右移位位置。如果为正,则结果与; 相同。如果是负的,其结果是等于表达的,

  • 问题内容: 如何在SQL Server中编写无符号右移运算符?表情就像 这是例如 -5381 >>> 0 = 4294961915 问题答案: T-SQL没有移位运算符,因此您必须自己实现。这里有一个按位移位的实现:http : //dataeducation.com/bitmask- handling-part-4-left-shift-and-right-shift/ 您必须将整数强制转换为v