Как преобразовать signed в unsigned integer в python
допустим, у меня есть этот номер i = -6884376
.
Как я могу ссылаться на него как на беззнаковую переменную?
Что-то вроде (unsigned long)i
В С.
4 ответов
предполагая, что:
- у вас есть 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