PHP эквивалентный JavaScript >>> Shift прямо с нулевым заполнитеми побитовые операторы?
-
27-09-2019 - |
Вопрос
Могу ли я узнать, как я могу сделать PHP >>>? Такие операторы недоступны в PHP, но доступны в JavaScript.
Мне просто удалось обнаружить функцию, как следует следующим образом:
function zeroFill($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;
}
Но, к сожалению, это не работает отлично.
Например: -1149025787 >>> 0 JavaScript возвращает 3145941509 PHP Zerofill () Return 0
Решение 4
Я учился вокруг сетей и выходил со своей собственной функцией ZeroFill, база на объяснении. Этот метод работает для моей программы.
Посмотри:
function zeroFill($a,$b) {
if ($a >= 0) {
return bindec(decbin($a>>$b)); //simply right shift for positive number
}
$bin = decbin($a>>$b);
$bin = substr($bin, $b); // zero fill on the left side
$o = bindec($bin);
return $o;
}
Другие советы
/**
* The >>> javascript operator in php x86_64
* Usage: -1149025787 >>> 0 ---> rrr(-1149025787, 0) === 3145941509
* @param int $v
* @param int $n
* @return int
*/
function rrr($v, $n)
{
return ($v & 0xFFFFFFFF) >> ($n & 0x1F);
}
/**
* The >> javascript operator in php x86_64
* @param int $v
* @param int $n
* @return int
*/
function rr($v, $n)
{
return ($v & 0x80000000 ? $v | 0xFFFFFFFF00000000 : $v & 0xFFFFFFFF) >> ($n & 0x1F);
}
/**
* The << javascript operator in php x86_64
* @param int $v
* @param int $n
* @return int
*/
function ll($v, $n)
{
return ($t = ($v & 0xFFFFFFFF) << ($n & 0x1F)) & 0x80000000 ? $t | 0xFFFFFFFF00000000 : $t & 0xFFFFFFFF;
}
Наслаждайся этим.
В два раза быстрее для отрицательных чисел, используя десятичные двоичные преобразования
function zerofill($a,$b) {
if($a>=0) return $a>>$b;
if($b==0) return (($a>>1)&0x7fffffff)*2+(($a>>$b)&1);
return ((~$a)>>$b)^(0x7fffffff>>($b-1));
Я много исследовал на этом, собрал более 11 версий из проектов Stackoverflow и с открытым исходным кодом, ни один из них не работал. Но, наконец, я нашел решение.
Для получения более подробной информации о живых демо, тесты и примеры проверяют мой вопрос и ответ:
Правый сдвиг без подписи / нулевой наполнение в PHP (эквивалент Java / JavaScript)
function unsignedRightShift($a, $b) {
if ($b >= 32 || $b < -32) {
$m = (int)($b/32);
$b = $b-($m*32);
}
if ($b < 0) {
$b = 32 + $b;
}
if ($b == 0) {
return (($a>>1)&0x7fffffff)*2+(($a>>$b)&1);
}
if ($a < 0)
{
$a = ($a >> 1);
$a &= 0x7fffffff;
$a |= 0x40000000;
$a = ($a >> ($b - 1));
} else {
$a = ($a >> $b);
}
return $a;
}
Ваша функция не работает, потому что когда $b == 0
, выражение
$a >> -1
будет оцениваться, что возвращает 0.
Предполагая 32-битные машины, вы можете добавить особый случай:
if ($z & $a) {
if ($b == 0)
return $a + 0x100000000;
else {
...
Не уверены, если это работает для PHP, мне удалось заставить его работать с C #.
int a, b, result;
//Instead of
result = a >>> b;
//I do
result = (int)((uint)a >> b);
Я обнаружил, что отладив в код, который использует >>>
Сравнивая его с помощью C # версией кода, который я преобразовал из JavaScript. Пробуясь с b = 0
, и используя научный калькулятор, чтобы увидеть различные шестигранные / декабря >>
а также >>>
производить с помощью JavaScript. Когда a
негативно, >>>
на самом деле делает AA как без подписи.
Не уверен, что работает для всех сценариев, но для моего случая >>>
для хеширования MD5. Возможность создавать аналогичный выход, я вполне доволен результатом.
надеюсь, это поможет
Для обоих 32-битных (php_int_size == 4) и 64-битные целые числа (php_int_size == 8):
function SHR
($x, $c)
{
$x = intval ($x); // Because 13.5 >> 0 returns 13. We follow.
$nmaxBits = PHP_INT_SIZE * 8;
$c %= $nmaxBits;
if ($c)
return $x >> $c & ~ (-1 << $nmaxBits - $c);
else
return $x;
}
Это работает для меня
function RRR($a, $b){
return (int)((float)$a/pow(2,(int)$b));
}