2013-01-20 7 views
5

PHPで符号なしの右シフトをプリフォームするために私のメソッドを使用すると、その数値に負の値が含まれていると結果が正しくありません。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; 
+0

あなたの結果がコードにどのように対応しているかは不明です。入力と出力の使い方を明確に示す[最小限のテストケース](http://sscce.org)を作成できますか? –

+0

私はそれが入力と出力が何であるかはっきりしているので修正しました。 –

答えて

6

これuRShiftは、短い32ビットおよび64ビットのPHPで正しく動作とJavaと同じサイズのint値を有する32ビットのPHPで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 
+0

以下の例をシフトすると動作しません。-672461345 >>> 25 JSによると107になるはずですが、549755813867が返されます。私はあなたのコードを検索し、いくつかのオープンソースプロジェクトでそれを見つけました。私はこれを使用しようとしています。 もっと見る:http://stackoverflow.com/questions/24659911/unsigned-right-shift-function-not-working-for-negative-input – frzsombor

+0

注意! JavaScriptと同じ出力を提供するPHP関数を探しているなら、私は最終的に実用的な解決策を見つけました!詳細、ライブデモ、テスト、例:http://stackoverflow.com/a/43359819/2953830 – frzsombor

2

は、代わりにこの機能を試してみてください。

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