2010-07-24 66 views
0

我想实现DataOutputStream类在PHP (从Java语言DataOutputStream类)在Java代码 他们右移变量,像这样>>>PHP右移

在PHP我只能转向像这样>>

我该如何在PHP中做到这一点?

谢谢

回答

4

您可以implement the behavior of the unsigned right shift operator >>> with the signed shift operators这样的:

n>>>s值是n右移s位零扩展位置。如果n为正,则结果与n>>s相同;如果n为负,其结果是等于表达(n>>s)+(2<<~s)的,如果左边的操作数的类型是INT,并以表达(n>>s)+(2L<<~s)的结果,如果左侧操作数的类型是 。所添加的术语(2<<~s)(2L<<~s)将消除传播的符号位。

+1

所以这是我必须做的 私有函数shiftRight3($ A,$ b){ 如果(is_n umeric($ a)&& $ a <0){ return $ a >> $ b +(2 <<〜$ b); } else { return $ a >> $ b; } } – shay 2010-07-24 16:28:49

+1

@ shay:是的,确切的。 – Gumbo 2010-07-24 16:43:23

+0

谢谢大家:) – shay 2010-07-24 16:57:50

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