PHP сдвиг вправо - PullRequest
       1

PHP сдвиг вправо

0 голосов
/ 24 июля 2010

я пытаюсь реализовать DataOutputStream в PHP (DataOutputStream от языка Java) в коде Java они сдвигают правильные переменные, как это >>>

в php я могу только так сдвигаться >>

как я могу сделать это в php?

спасибо

Ответы [ 2 ]

4 голосов
/ 24 июля 2010

Вы можете реализовать поведение беззнакового оператора сдвига вправо >>> с помощью операторов сдвига со знаком следующим образом:

Значение n>>>s равно n смещенным вправо s позициям битов с нулевым расширением. Если n положительно, то результат такой же, как у n>>s; если n отрицательно, результат равен результату выражения (n>>s)+(2<<~s), если тип левого операнда равен int , и результату выражения (n>>s)+(2L<<~s), если тип левого операнда имеет длину . Добавленный термин (2<<~s) или (2L<<~s) отменяет распространяющийся бит знака.

0 голосов
/ 21 марта 2014

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...