Я ищу способ использовать функцию >>>
из JavaScript в 64-разрядной версии PHP 5.5.14. Я нашел эту функцию в своем googling:
function uRShift($a, $b) { $z = hexdec(80000000); if ($z & $a) { $a = ($a >> 1); $a &= (~$z); $a |= 0x40000000; $a = ($a >> ($b - 1)); } else { $a = ($a >> $b); } return $a; }
Эта функция работает нормально для положительных чисел, но я получаю разные результаты при прохождении отрицательных чисел.
Например:
PHP:
In: echo uRShift(-672461345, 25); Out: -149
JavaScript (Chrome 35):
In: -672461345 >>> 25 Out: 107
РЕДАКТИРОВАТЬ:
Я также попробовал другую функцию, указанную в ответе, указанном выше.
function uRShift($a, $b) { if($b == 0) return $a; return ($a >> $b) & ~(1<<(8*PHP_INT_SIZE-1)>>($b-1)); }
PHP:
In: echo uRShift(-672461345, 25); Out: 549755813867
Runnable
Константа 0x80000000
(она написана как вызов hexdec
и хранится в переменной $z
в этом примере) представляет собой отрицательное целое число с отрицательным hexdec
( 100000....
в двоичном формате). Выражение ~$z
должно давать побитовое NOT этого, а именно наивысшее положительное целое число (которое заканчивается 2147483647
).
Исходный номер ( положительный 0x80000000
, то есть 2147483648
) не может быть сохранен в виде 32-битного целого числа, поэтому обычно он будет храниться как поплавок какого-либо типа. К сожалению, PHP 5.5 считает, что ~(2147483648)
равно -2147483649
, что было бы правильно, если бы мы имели дело, например, с 64-битными целыми числами .
И действительно, повторение PHP_INT_SIZE
в runnable указывает, что целые числа составляют 8 байтов, что составляет 64 бита. Таким образом, арифметика не работает прямо в PHP 5.5.
Чтобы исправить это, просто замените ~$z
статической константой следующим образом:
function uRShift($a, $b) { if ($a < 0) { $a = ($a >> 1); $a &= 2147483647; $a |= 0x40000000; $a = ($a >> ($b - 1)); } else { $a = ($a >> $b); } return $a; }
Эта функция по-прежнему имеет некоторые недостатки; например, смещение на 0 не работает должным образом.