Битовые сдвиги в python

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті.

Вопрос в том, что в питоне битовые (bit-shift >> and <<) сдвиги «иные», т.е. с учетом знака:) А есть ли способ получить обычные битовые сдвиги. как в С или том же ПХП.Т. е. чтобы биты просто сдвигались в лево (к примеру), без учета знакового/не знакового бита, а «лишние» биты не расширяли число до long, а просто отбрасывались.

Приведу пример кода на ПХП:

$Check1 = StrToNum ($String, 0×1505, 0×21);

$Check2 = StrToNum ($String, 0, 0×1003F);

$Check1 >> = 2;

$Check1 = (($Check1 >> 4) & 0×3FFFFC0) | ($Check1 & 0×3F);

$Check1 = (($Check1 >> 4) & 0×3FFC00) | ($Check1 & 0×3FF);

$Check1 = (($Check1 >> 4) & 0×3C000) | ($Check1 & 0×3FFF);

$T1 = (((($Check1 & 0×3C0) << 4) | ($Check1 & 0×3C)) << 2) | ($Check2 & 0xF0F);

$T2 = (((($Check1 & 0xFFFFC000) << 4) | ($Check1 & 0×3C00)) << 0xA) | ($Check2 & 0xF0F0000);

return ($T1| $T2);

Простое преобразование его к питоньему синтаксису дает иной результат...

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Да и вообще, на пхп то оно как раз раотает как надо, мне на питоне хочется повторить битовые сдвиги пхп:)

Тоже не совсем подходящий способ. Допустим я сбросил знаковый бит, т.е. 16 бит у нас теперь ноль и мы делаем сдвиг влево, а в 15 у нас единичка. Так эта единичка у нас не переедит в 16, а у нас расширится число до типа лонг, что тоже не совсем то, что хотелось бы получить:)

И ещё. В оригинальном коде есть 0×3FFFFC0, если по-хорошему, то лидирующие нули надо записывать всегда, чтобы избегать ошибок при написании и чтении, особенно когда написано 7 нибблов вместо 8.

К примеру можно вот это:
...
$Check1 >> = 2;
$Check1 = (($Check1 >> 4) & 0×3FFFFC0) | ($Check1 & 0×3F); ...
заменить на:
$Check1 >> = 2;
$Check1 & = 0×3FFFFFFF;
$Check1 = (($Check1 >> 4) & 0×03FFFFC0) | ($Check1 & 0×3F);
Просто убив сам знак и все реплицированные знаки в старших битах. При отсутствии математических операций и при использовании только бинарных всё должно быть нормально.
При знаковом сдвиге влево на 1, всё нормально:
-300 = FFFF FED4 = 1111 1111 1111 1111 1111 1110 1101 0100
-600 = FFFF FDA8 = 1111 1111 1111 1111 1111 1101 1010 1000
При знаковом сдвиге вправо на 1 реплицируется бит знака:
-300 = FFFF FED4 = 1111 1111 1111 1111 1111 1110 1101 0100
-150 = FFFF FF6A = 1111 1111 1111 1111 1111 1111 0110 1010

Достаточно принудительно снимать старший бит: & 0×7FFFFFFF при сдвиге на 1 вправо, либо снимать то количество битов, на которое был произведён сдвиг.

Підписатись на коментарі