Дата и время публикации:
Проблема и решение
1. Суть проблемы
По умолчанию, в Python все побитовые операции производятся со знаковыми целами (signed int), что неминуемо приводит к следующим удивительным результатам, как показано в дампе 1.1 :
Дамп 1.1, пример побитовой операции в python co целыми числами со знаком
>>> x = 0xFF00 >>> y = ~x >>> print ( "x=%5.4x,y=%5.4x" % (x,y) ) x= ff00,y=-ff01 >>> x 65280 >>> y -65281
Ярким представителем битовых операций является операция НЕ (~), которая иллюстрирует проблему операций с целыми числами со знаком, тип которых (signed int) по умолчанию использованию python
Проблема с использованием побитовой операции НЕ (~) достаточно известная и вместно нее рекомендуется использовать оператор вычитания [3.1], как показано в дамп 2.2 :
Дамп 2.2, рекомендуемый аналог побитовой
>>> z = 0xFFFF - x >>> hex(z) '0xff'
Что не совсем удобно, несмотря на верный полученный результат, потому что для выполнения такого рода операции нужно иметь не только вычитамое (x), но и уменьшаемое (0xFFFF), которое должно быть известно. Особенно, неудобно, когда речь идет не только об 16-ти разрядных целых без знака (тип unsigned short) или 8-ми таким же разрядных (тип unsigned char), но и об 32-х и 64-х разрядных, соответственно, имеющих тип unsigned int и unsigned long.
2. Решение
Поэтому,чтобы этого избежать этого, оказалось самым простым использовать Python модуль numpy, как показано в дампе 2.1 :
Дамп 2.1, использование модуль numpy
>>> import numpy as np >>> >>> x = np.uint16(0xff00) >>> bin(x) '0b1111111100000000' >>> y = ~x >>> bin(y) '0b11111111' >>> y 255
который предоставляет псевдонимы к классам безнаковых целых чисел [3.3], совместимых с соответствующими типами в языке программирования С :
numpy.uint8 — псевдоним класса numpy.ubyte, совместимого с типом unsigend char
numpy.uint16 — псевдоним класса numpy.ushort, совместимого с типом unsigned short
numpy.uint32 — псевдоним класса numpy.uintc, совместимого с типом unsigned int (32 разряда) или в некоторых вычислительных платформах, обозначаемого uint32
numpy.uint64 — псевдоним класса numpy.uint, совместимого с типом unsigned long (64 разряда) или в некоторых вычислительных платформах, обозначаемого uint64
3. Библиография
3.1 Stackoverflow -- How do I do a bitwise Not operation in Python?