PHP Неподписанный Сдвиг вправо - Неисправен
Итак, при использовании моего метода для предварительной обработки (>>>) сдвига вправо без знака в 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;
5
Author: Mitchell M, 2013-01-20
2 answers
Этот 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
8
Author: Joachim Isaksson, 2013-01-20 19:39:50
Попробуйте вместо этого использовать эту функцию.
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;
}
3
Author: WhyteWolf, 2013-01-20 19:29:12