Форум сайта python.su
Люди умные, помогите :)
Возник вопрос по битовым сдвигам (>> и <<)
Есть 2 языка PHP и Python и в них одна и таже битовая строка ПОЧЕМУ-ТО становится различными числами
Т.е. есть такиое числа в PHP:
$Check1 =2384889349; // что представляет собой 10001110001001101000011000000101
Дальше берем
$Check1 >>= 2;
И получаем
$Check1 = -477519487; // 11100011100010011010000110000001
Если все тоже провернуть в питоне, то
Check1 = 2384889349L #10001110001001101000011000000101
Делаем
Сheck1 >>= 2
И получаем
Check1 = 596222337L #100011100010011010000110000001
Т.е. вроде битово все сходится, а числа разные… А число -477519487 в питоне представляет собой 11100011101100101111001111111
Почему такое разное поведение, может кто что-то дельное подскажет, в какую сторону копать.
Причем то, как ведет себя ПХП меня устраивает именно этот ответ я ожидаю получить. Как получить такой же ответ в питоне…
Офлайн
модуль struct должен помочь
Офлайн
Хм, а Вы заметили, что оператор сдвига в пхп добавляет единицы, в результате чего получаем отрицательное число(единичка в старшем разряде), а в пайтоне при сдвиге добавляются нули =). Давно не работал с информацией по-битово, но кажется были какие-то функции, в которых можно было указывать, чем заполнять освободившиеся в результате сдвига позиции. А вообще немного странная задача для скриптовых языков и тем более для языков без строгой типизации =). Копать надо в реализации типов данных, в вашем случае Integer и Long Integer в этих языках. Они могут элементарно содержать разное количество байт, тем более непонятно они вообще Unsigned или signed и т.п. и т.д.
Отредактировано (Сен. 2, 2009 20:15:18)
Офлайн
NSkrypnikТа нет, как раз все понятно. В питоне нет беззнаковых типов вообще, а сдвиги арифметические (т.е. с учетом того самого знака), а мне нужны не арифметические, а “обычные, человечески”. В пхп именно такие. Думал может кто просто сталкивался с этим и как-то обходил. И с каких пор питон стал языком с нестрогой типизацией? ;)
Хм, а Вы заметили, что оператор сдвига в пхп добавляет единицы, в результате чего получаем отрицательное число(единичка в старшем разряде), а в пайтоне при сдвиге добавляются нули =). Давно не работал с информацией по-битово, но кажется были какие-то функции, в которых можно было указывать, чем заполнять освободившиеся в результате сдвига позиции. А вообще немного странная задача для скриптовых языков и тем более для языков без строгой типизации =). Копать надо в реализации типов данных, в вашем случае Integer и Long Integer в этих языках. Они могут элементарно содержать разное количество байт, тем более непонятно они вообще Unsigned или signed и т.п. и т.д.
Отредактировано (Сен. 2, 2009 20:27:39)
Офлайн
Да, ерунду написал по поводу типизации . Имел в виду то, что интерпретатор сам определяет тип переменной и с этим тоже могут быть сюрпризы.
11100011100010011010000110000001 - 4 байта. Пхп может его воспринимает, как sign integer, тогда получается отрицательное число, а питон думает, что это лонг инт (L - на конце) 8-ми байтовый, вот Вам и другое число.
Отредактировано (Сен. 2, 2009 20:40:28)
Офлайн
Побитовые операции над стандартными типами данных не дадут нужного результата (именно циклический сдвиг) в виду того, что в питоне не происходит переполнения int-го числа, оно автоматом преобразуется в long, т.е. нет фиксированного размера. В py3k вообще нет такого типа данных как long, его заменил int, у которого появился метод bit_length. Для циклического сдвига гугл подсказывает вот это: http://cobweb.ecn.purdue.edu/~kak/dist/BitVector-1.5.1.html, но можно и ещё поискать, либо самому написать, это совсем не трудно.
Офлайн
Всем спасибо. Натолкнули на правильные мысли. Одна бессонная ночь, и я таки заставил их считать так как надо мне :)
Пришлось правда самому написать функцию сдвига вправо и функцию проверки знака. Если кому интересно, то привожу их текст:
def check_sign(i):
“”“check sign-bit and fix it”“”
if i & 0x80000000:
i = -((i^0xffffffff)+1)
return i
def int2bin(n, count=32):
“”“returns the binary of integer n, using count number of digits”“”
return “”.join()
def rshift(val, count):
“”“do right bit-shift of integer val on count bits and check sign-bit”“”
bit = int2bin(val, 32)
bit_str = bit*count + int2bin(val >> count, 32 - count)
return check_sign(int(bit_str, 2))
Офлайн