Пытаясь ответить на другой пост, в котором решение касается IP-адресов и сетевых масок, я застрял в простой побитовой арифметике.
Есть ли в Python стандартный способ выполнения побитовых операций И, ИЛИ, ИСКЛЮЧАЮЩЕЕ ИЛИ, НЕ, предполагая, что входные данные представляют собой «32-битные» (возможно, отрицательные) целые или длинные числа, и что результат должен быть длинным в диапазоне [ 0, 2 ** 32]?
Другими словами, мне нужен рабочий Python-аналог побитовых операций C между беззнаковыми long.
Обновлено: конкретная проблема заключается в следующем:
>>> m = 0xFFFFFF00 # netmask 255.255.255.0
>>> ~m
-4294967041L # wtf?! I want 255
Начиная с Python 3.3, некоторые пользователи, столкнувшиеся с этим, могут быть заинтересованы в модуль ipaddress.






from numpy import uint32
@gerrit Имеется в виду, что он требует, чтобы в системе был установлен модуль numpy, тогда как ctypes является частью ядра Python?
Вы можете использовать ctypes и его c_uint32:
>>> import ctypes
>>> m = 0xFFFFFF00
>>> ctypes.c_uint32(~m).value
255L
Итак, что я здесь сделал, это преобразовал ~m в 32-битное беззнаковое целое число C и получил его значение обратно в формате Python.
С помощью 0xFFFFFFFF можно все замаскировать:
>>> m = 0xFFFFFF00
>>> allf = 0xFFFFFFFF
>>> ~m & allf
255L
Эта стратегия также помогает с арифметика bash.
Вы делаете на одну операцию больше, чем необходимо. И выполнение НЕ - это то же самое, что XOR. Итак, m ^ allf - это то, что вам нужно.
@mlefavor Я не знаю, откуда вы взяли, что ~a & b - это то же самое, что и a ^ b. Это не в общем.
Я полагаю, это было чрезмерно с моей стороны. Но я думаю, что это правда в случае 0xFFFFFFFF.
См. Эту вики, чтобы узнать, почему маска нужна: wiki.python.org/moin/BitwiseOperators В двух словах, отрицательные числа обрабатываются так, как если бы они имели бесконечное количество ведущих единиц. Битовая маска удаляет все цифры, кроме необходимого количества цифр.
Это модуль, который я создал очень давно, и он может вам помочь:
Он предоставляет как минимум класс CIDR с подсетевой арифметикой. Посмотрите примеры тестов в конце модуля.
Вы также можете выполнить xor с 0xFFFFFFFF, что эквивалентно «беззнаковому дополнению».
>>> 0xFFFFFF00 ^ 0xFFFFFFFF
255
Я полагаю, что некорректная типизация Pythons сыграла бы в аду с любым подобным алгоритмом ... Я тоже хочу его увидеть, просто из любопытства.