× К оглавлению На главную Об авторе

Дата и время публикации:    

Проблема и решение

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?

3.2 NumPy -- Sized aliases.

3.3 NumPy -- Unsigned integer types

Сайт разработан в соответствии с рекомендациями консорциума W3C для языка разметки HTML5.

Об авторе можно прочитать здесь.

Copyright © 2015-2019 Андрей Ржавсков