2010-07-24 4 views
0

я пытаюсь реализовать DataOutputStream в PHP (DataOutputStream от языка Java) в 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 ($ а, $ б) { если (is_n umeric ($ a) && $ a <0) { return $ a >> $ b + (2 << ~ $ b); } else { return $ a >> $ b; } } – shay

+1

@shay: Да, точно. – Gumbo

+0

спасибо всем :) – shay

0

В замаскированной форме для любой платформы (32bit, 64bit ... в будущем до тех пор, как 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), но ниже Int значение минимального для PHP: -2147483648

Смежные вопросы