Как преобразовать отрицательное целое число в шестнадцатеричный в Python - PullRequest
20 голосов
/ 19 октября 2011

Я использую Python 2.6

>>> hex(-199703103)
'-0xbe73a3f'

>>> hex(199703103)
'0xbe73a3f'

Положительные и отрицательные значения одинаковы?

Когда я использую calc, значение равно FFFFFFFFF418C5C1.

Ответы [ 4 ]

43 голосов
/ 19 октября 2011

Целые числа Python могут расти произвольно большими. Чтобы вычислить необработанные two's -plement так, как вы этого хотите, вам нужно указать желаемую ширину в битах. Ваш пример показывает -199703103 в 64-разрядном двоичном дополнении, но он также может быть 32-разрядным или 128-разрядным, что приведет к другому количеству 0xf в начале.

hex() не делает этого. В качестве альтернативы я предлагаю следующее:

def tohex(val, nbits):
  return hex((val + (1 << nbits)) % (1 << nbits))

print tohex(-199703103, 64)
print tohex(199703103, 64)

Это распечатывает:

0xfffffffff418c5c1L
0xbe73a3fL
11 голосов
/ 19 октября 2011

Поскольку целые числа Python произвольно велики, необходимо замаскировать значения, чтобы ограничить преобразование тем количеством бит, которое вы хотите для представления дополнения 2s.

>>> hex(-199703103 & (2**32-1)) # 32-bit
'0xf418c5c1L'
>>> hex(-199703103 & (2**64-1)) # 64-bit
'0xfffffffff418c5c1L'

Python отображает простой случай hex(-199703103) как отрицательное шестнадцатеричное значение (-0xbe73a3f), потому что представление дополнения 2s будет иметь бесконечное число F перед ним для числа произвольной точности. Значение маски (2 ** 32-1 == 0xFFFFFFFF) ограничивает это:

FFF...FFFFFFFFFFFFFFFFFFFFFFFFF418c5c1
&                             FFFFFFFF
--------------------------------------
                              F418c5c1
1 голос
/ 11 мая 2018

Добавление к Отмечает ответ , если вы хотите другой формат вывода, используйте

'{:X}'.format(-199703103 & (2**32-1))
0 голосов
/ 08 января 2017
>>> import struct
>>> struct.pack("i", -4)
'\xfc\xff\xff\xff'
...