Просмотр полной версии : Циклический битовый сдвиг в PHP
Очень нужно реализовать на PHP функцию циклического сдвига 32 битного числа.
в ассемблере просто всё - ror/rol а в PHP такого нет.
Вообще нашел только << и >> но это не циклический сдвиг.
Пытался сам реализовать через операции
$k = $k >> 3 + $k << 29;
В других языках (компилируемых) такое прокатилобы, а вот в PHP почемуто не пашет.
Pashkela
03.06.2010, 19:46
http://www.rinatous.com/blog/node/1.html
и? В чем смысл того, что ты дал? Там рассматриваются непосредственно операции над битами, это есть в любой доке по PHP
А тут нужно именно циклический сдвиг
фуф. вопрос решил сам. почемуто такое стало работать
$k = ($k << 29) + ($k >> 3);
и в одном месте chr() забыл
roxblnfk
03.06.2010, 20:29
Такое работает не при всех вариантах. Если левый бит равен 1, то заливка слева после смещения будет единицами, что при сложении не допустимо..
Написал код (про моём тестировании всё нормально):
$k=bindec('11111100110011001100110011000000');
echo sprintf('%032b',$k).'<br>';
for($a=1;$a<=32;$a++){
$b=32-$a;
$s = (($k >> $a) & ~(-pow(2,$b)))^($k << $b);
echo sprintf('%032b',$s).'<br>';
}
Результат:
11111100110011001100110011000000
01111110011001100110011001100000
00111111001100110011001100110000
00011111100110011001100110011000
00001111110011001100110011001100
00000111111001100110011001100110
00000011111100110011001100110011
10000001111110011001100110011001
11000000111111001100110011001100
01100000011111100110011001100110
00110000001111110011001100110011
10011000000111111001100110011001
11001100000011111100110011001100
01100110000001111110011001100110
00110011000000111111001100110011
10011001100000011111100110011001
11001100110000001111110011001100
01100110011000000111111001100110
00110011001100000011111100110011
10011001100110000001111110011001
11001100110011000000111111001100
01100110011001100000011111100110
00110011001100110000001111110011
10011001100110011000000111111001
11001100110011001100000011111100
01100110011001100110000001111110
00110011001100110011000000111111
10011001100110011001100000011111
11001100110011001100110000001111
11100110011001100110011000000111
11110011001100110011001100000011
11111001100110011001100110000001
11111100110011001100110011000000
При использовании твоего кода:
11111100110011001100110011000000
11111110011001100110011001100000
11111111001100110011001100110000
11111111100110011001100110011000
11111111110011001100110011001100
11111111111001100110011001100110
11111111111100110011001100110011
01111111111110011001100110011001
10111111111111001100110011001100
01011111111111100110011001100110
00101111111111110011001100110011
10010111111111111001100110011001
11001011111111111100110011001100
01100101111111111110011001100110
00110010111111111111001100110011
10011001011111111111100110011001
11001100101111111111110011001100
01100110010111111111111001100110
00110011001011111111111100110011
10011001100101111111111110011001
11001100110010111111111111001100
01100110011001011111111111100110
00110011001100101111111111110011
10011001100110010111111111111001
11001100110011001011111111111100
01100110011001100101111111111110
00110011001100110010111111111111
10011001100110011001011111111111
11001100110011001100101111111111
11100110011001100110010111111111
11110011001100110011001011111111
11111001100110011001100101111111
11111001100110011001100110000000
как видно в первых строках нули не появляются слева
фуф. вопрос решил сам. почемуто такое стало работать
$k = ($k << 29) + ($k >> 3);
ну да, надо скобки ставить. и в сях вообще-то тоже надо. У сдвигов приоритет выше (вроде) только чем у присваивания.
И лучше не + писать, а |.
vBulletin® v3.8.14, Copyright ©2000-2026, vBulletin Solutions, Inc. Перевод: zCarot