frz*_*bor 6 javascript php java bit-manipulation bit-shift
在将此标记为重复之前,请阅读以下内容,并检查我的代码*我的更新代码!
所以我的问题是,我必须实现Java/JavaScript'>>>'(无符号右移/零填充右移),但我无法以完全相同的方式工作.
我已经选择了我在SO和Web上找到的11个最有希望的实现(链接在代码中添加为注释)并添加了一些测试用例.不幸的是无功能返回的Java/JS相同响应所有的测试.(也许其中一些只在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));
}
Run Code Online (Sandbox Code Playgroud)
和
// 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;
}
Run Code Online (Sandbox Code Playgroud)
不幸的是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
Run Code Online (Sandbox Code Playgroud)
编辑:我发现这只是在JavaScript中-3 >>> 0等于(为什么?),但在Java中,它等于.不幸的是,这并没有改变我仍然无法通过所有测试的任何功能的事实.4294967293-3
*大更新:
从PHP 7开始,位移负数被认为是无效的并且导致:" 致命错误:未捕获的算术错误:按负数移位 ".据此,我认为我们不必通过这些测试,所以我已经更新了问题和代码.
在研究了问题中的两个函数(“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;
}
Run Code Online (Sandbox Code Playgroud)
这段代码不仅准确,而且速度也很快。
基准测试结果:100000 次循环:0.25 秒
基准测试:http : //phpfiddle.org/main/code/mj68-1s7e