0


0

PHPの右シフト

私はPHPのDataOutputStream(Java言語のDataOutputStream)をJavaコードで実装しようとしています

PHPでは、このようにしかシフトできません>>

どうすればPHPでこれを行うことができますか?

ありがとうございました

2 Answer


4


http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.19 [符号なしシフトで符号なし右シフト演算子「>>>」の動作を実装できます。演算子]このような:

_ n >>> s`の値は n`右シフトした s`ビット位置をゼロ拡張したものです 「n」が正の場合、結果は「n >> s」の結果と同じです。 「n」が負の場合、結果は式「(n >> s)+(2 <<〜s)」の結果と等しくなります。左側のオペランドの型が_int_の場合、および左側のオペランドの型が_long_の場合、式 `(n >> s)+(2L <<〜s)。 追加された用語 `(2 <<〜s)`または `(2L <<〜s)`は、伝播された符号ビットを取り消します。 _


0


任意のプラットフォームのマスク形式(32ビット、64ビット…​ 「PHP_INT_MAX」が定義されている限り、将来的に)パフォーマンスの利点を提供します(分岐なし):

function uintRShift($uint,$shift)
{
    //if ($shift===0) return $uint;
    //PHP_INT_MAX on 32 =7FFFFFFF, or zero & 32 ones
    $mask=PHP_INT_MAX>>($shift-1);
    return $uint>>$shift&$mask;
}

マスク設定は、「$ uint」の左端の「$ shift」ビットにすべてゼロを置きます。 _注意:_負の数/大きな数をゼロシフトできるようにしたい場合は、最初の行のコメントを外します( `$ shift = 0`でもマスクが負の数/大きな数を変更するため)。

32ビットで動作することを示す単体テストコード:

class UintRShiftTest extends PHPUnit_Framework_TestCase {
   public function provide_shifts() {
      return array(
         /*   start         shift       end*/
          array(0,          4,          0)
         ,array(0xf,        4,          0)
         ,array(0xff,       4,          0xf)
         ,array(0xfffffff,  4,          0xffffff)
         ,array(0xffffffff, 4,          0xfffffff)
         ,array(-1,         4,          0xfffffff)//Same as above
         ,array(0,          1,          0)
         ,array(0xf,        1,          0x7)
         ,array(-1,         1,          0x7fffffff)
         );
   }

   /**
    * @dataProvider provide_shifts
    */
   function test_uintRShift($start,$shift,$end) {
      $this->assertEquals($end,uintRShift($start,$shift));
   }
}

上記の機能に値するもの:

function uintRShift_branch($uint,$shift)
{
   if ($uint<0) {
      return ($uint>>$shift)+(2<<~$shift);
   } else {
      return $uint>>$shift;
   }
}

自動テストに不合格:

  • *#4 * `-1`を報告します。 これはおそらく、PHPレポートによって正当化される可能性があります 「0xffffffff」は大きな正数です(ドキュメントでは、大きな整数は自動的にフロートに切り替えられますが、ビットシフトでは通常の整数として扱われているようです)

  • *#8 *結果は「-2147483649」になりますが、これは実際には正しいです(と同じ 0x7fffffff)が、PHPの最小int値以下:` -2147483648`