时间:2010-07-24 15:24:04

标签: java php bit-manipulation

2 个答案:

答案 0 :(得分:4)

答案 1 :(得分: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;
}

掩码设置为$shift的最左侧$uint位添加全零。 注意:如果您希望能够/容忍零移位负数/大数,则取消注释第一行(因为即使使用$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 < / p>