Как преобразовать signed в unsigned integer в python

допустим, у меня есть этот номер i = -6884376. Как я могу ссылаться на него как на беззнаковую переменную? Что-то вроде (unsigned long)i В С.

4 ответов


предполагая, что:

  1. у вас есть 2-х-дополняют представления в виду; и,
  2. By (unsigned long) вы mean 32-разрядное целое число без знака,

тогда вам просто нужно добавить 2**32 (or 1 << 32) к отрицательному значению.

например, примените это к -1:

>>> -1
-1
>>> _ + 2**32
4294967295L
>>> bin(_)
'0b11111111111111111111111111111111'

Assumption #1 означает, что вы хотите, чтобы -1 рассматривался как сплошная строка из 1 бита, а assumption #2 означает, что вы хотите 32 их.

никто, кроме вас, не может сказать, каковы ваши скрытые предположения. Если, например, у вас есть представления дополнения 1, то вам нужно применить оператор префикс. Целые числа Python упорно работают, чтобы дать иллюзию использования бесконечно широкого представления дополнения 2 (например, дополнения regular 2, но с бесконечным количеством "знаковых битов").

и для дублирования того, что делает компилятор платформы C, вы можете использовать ctypes модуль:

>>> import ctypes
>>> ctypes.c_ulong(-1)  # stuff Python's -1 into a C unsigned long
c_ulong(4294967295L)
>>> _.value
4294967295L

С unsigned long бывает 4 байта на поле, которое запустило этот образец.


чтобы получить значение, эквивалентное вашему c cast, просто побитовое и с соответствующей маской. например, если unsigned long - это 32 разрядная версия:

>>> i = -6884376
>>> i & 0xffffffff
4288082920

или если это 64-битный:

>>> i & 0xffffffffffffffff
18446744073702667240

имейте в виду, что, хотя это дает вам значение, которое вы имели бы в C, это все еще знаковое значение, поэтому любые последующие вычисления могут дать отрицательный результат, и вам придется продолжать применять маску для имитации 32 или 64-битного вычисления.

это работает, потому что, хотя Python выглядит так, как будто он хранит все числа как знак и величину, побитовые операции определяются как работа над значениями дополнения two. C хранит целые числа в двойках, но с фиксированным числом битов. Побитовые операторы Python действуют на двоичные значения дополнения, но как будто они имеют бесконечное количество битов: для положительных чисел они простираются влево до бесконечности с нулями, но отрицательные числа простираются влево с единицами. The & оператор изменит эту левую строку единиц на нули и оставить вас только с битами, которые вписались бы в значение C.

отображение значений в hex может сделать это более ясным (и я переписал строку f как выражение, чтобы показать, что мы заинтересованы в 32 или 64 битах):

>>> hex(i)
'-0x690c18'
>>> hex (i & ((1 << 32) - 1))
'0xff96f3e8'
>>> hex (i & ((1 << 64) - 1)
'0xffffffffff96f3e8L'

для 32-битного значения в C положительные числа доходят до 2147483647 (0x7fffffff), а отрицательные числа имеют верхний бит от -1 (0xffffffff) до -2147483648 (0x80000000). Для значений, которые полностью вписываются в маску, мы можем обратный процесс в Python, используя меньшую маску для удаления бита знака, а затем вычитание бита знака:

>>> u = i & ((1 << 32) - 1)
>>> (u & ((1 << 31) - 1)) - (u & (1 << 31))
-6884376

или для 64-битной версии:

>>> u = 18446744073702667240
>>> (u & ((1 << 63) - 1)) - (u & (1 << 63))
-6884376

этот обратный процесс оставит значение неизменным, если бит знака равен 0, но, очевидно, это не истинный обратный, потому что если вы начали со значения, которое не вписывается в размер маски, то эти биты исчезли.


Python не имеет встроенных неподписанных типов. Вы можете использовать математические операции для вычисления new int, представляющий значение, которое вы получите в C, но нет" неподписанного значения " Python int. Python int-это абстракция целочисленного значения, а не прямой доступ к целому числу с фиксированным размером байта.


просто используйте abs для преобразования unsigned в signed в python

 a=-12
b=abs(a)
print(b)

выход: 12