PHP Unsigned Right Shift - Неисправность

Таким образом, при использовании моего метода для предварительного формирования ( >>> ) беззнакового сдвига вправо в PHP результат будет неверным, когда числа содержат отрицательные значения.

Результаты приложения PHP:

INPUT: 10 >>> 3
INPUT: -10 >>> 3
OUTPUT: 1
OUTPUT: 2684354558

РЕЗУЛЬТАТЫ ПРИМЕНЕНИЯ JAVA:

INPUT: 10 >>> 3
INPUT: -10 >>> 3
OUTPUT: 1
OUTPUT: 536870910

(Верхние результаты верны и сгенерированы Java, а нижние результаты неверны и сгенерированы PHP)

Только когда число отрицательное в PHP, оно терпит неудачу.

Сдвиги, используемые в этих приложениях:

Пожалуйста, помоги, если можешь!

Метод переключения в PHP:

function urshift($x, $n){
$mask = 0x40000000;
if ($x < 0){
    $x &= 0x7FFFFFFF;
    $mask = $mask >> ($n-1);
    $ret = ($x >> $n) | $mask;
    $ret = str_pad(decbin($ret), 32, '0', STR_PAD_LEFT);
    $ret[0] = '1';
    $ret = bindec($ret);
} else {
        $ret = (int)$x >> (int)$n;
}
return $ret;

person Mitchell M    schedule 20.01.2013    source источник
comment
Хорошо, не понятно, как ваши результаты соответствуют вашему коду. Не могли бы вы создать минимальный тестовый пример, который четко демонстрирует, как используются входные и выходные данные?   -  person Oliver Charlesworth    schedule 20.01.2013
comment
Я исправил это, чтобы было ясно, что такое ввод и вывод.   -  person Mitchell M    schedule 20.01.2013


Ответы (2)


Этот uRShift короче, корректно работает с 32- и 64-битным PHP и дает тот же результат, что и Java-версия на 32-битном PHP, которая имеет тот же размер целых чисел, что и Java;

function uRShift($a, $b)
{
    if($b == 0) return $a;
    return ($a >> $b) & ~(1<<(8*PHP_INT_SIZE-1)>>($b-1));
}

> uRShift(-10,3)  
536870910

> uRShift(10,3)
1
person Joachim Isaksson    schedule 20.01.2013
comment
Сдвиг в следующем примере не работает: -672461345 ››› 25 Согласно JS должно быть 107, однако он возвращает 549755813867 . Я искал ваш код и нашел его в нескольких проектах с открытым исходным кодом, и я собираюсь использовать его, так что было бы хорошо, чтобы прояснить ситуацию. Подробнее: stackoverflow.com/questions/24659911/ - person frzsombor; 27.11.2016
comment
ВНИМАНИЕ! Если вы ищете функцию PHP, которая дает тот же результат, что и JavaScript, я наконец нашел работающее решение! Дополнительные сведения, живая демонстрация, тесты, примеры: stackoverflow.com/a/43359819/2953830 - person frzsombor; 19.04.2017

попробуйте эту функцию вместо этого.

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; 
}  
person WhyteWolf    schedule 20.01.2013