Как напечатать целое число со знаком в виде шестнадцатеричного числа в дополнении до двух с помощью python?

У меня есть отрицательное целое число (4 байта), из которого я хотел бы иметь шестнадцатеричную форму его двух дополнительных представлений.

>>> i = int("-312367")
>>> "{0}".format(i)
'-312367'
>>> "{0:x}".format(i)
'-4c42f'

Но я бы хотел увидеть "FF..."


person none    schedule 13.07.2010    source источник
comment
'шестнадцатеричная форма представления дополнения до двух' ? Чем это хоть немного полезно?   -  person Konrad    schedule 13.07.2010
comment
Посмотрите, подходит ли вам этот ответ на связанный вопрос: stackoverflow.com/questions/1604464/twos-complement-in-python/   -  person sarnold    schedule 13.07.2010
comment
Конрад, возможно, он готовит инструмент, чтобы показать своим ученикам, как это делается. Или ему любопытно. Или у него есть API для подражания. Или приятель поспорил с ним на ящик пива, что Perl сделает это лучше.   -  person sarnold    schedule 13.07.2010
comment
Да, свойство bitstrings hex, похоже, тоже возвращает то, что мне нужно. Спасибо.   -  person none    schedule 13.07.2010
comment
@ Конрад, 1: Нет, почему? @ Konrad, 2: Извините, если вам непонятно, что я имею в виду - как бы вы выразились?   -  person none    schedule 13.07.2010
comment
@Конрад, если он на уроке менеджмента, значит, он все делает правильно (делегируя) :-)   -  person JS.    schedule 13.07.2010
comment
@Konrad Иногда это полезно для отладки двоичных файлов.   -  person Quantum7    schedule 05.09.2013


Ответы (6)


Вот способ (для 16-битных чисел):

>>> x=-123
>>> hex(((abs(x) ^ 0xffff) + 1) & 0xffff)
'0xff85'

(Возможно, это не самый элегантный способ)

person adamk    schedule 13.07.2010
comment
Это не работает для положительных чисел. Если x=1, вы получите 0xffff (-1 в 16-битном дополнении до двух) вместо 0x0001. - person dcoles; 28.08.2015
comment
Приведенный пример был отрицательным целым числом, но вопрос заключался в том, как напечатать целое число со знаком... в дополнении до двух [представление]. Это может сбить с толку, если этот ответ работает только для целых чисел с отрицательным знаком. - person dcoles; 10.09.2015

С помощью модуля bitstring:

>>> bitstring.BitArray('int:32=-312367').hex
'0xfffb3bd1'
person Scott Griffiths    schedule 13.07.2010

Простой

>>> hex((-4) & 0xFF)
'0xfc'
person siu    schedule 27.08.2014

Чтобы рассматривать целое число как двоичное значение, вы побитовое и с маской желаемой битовой длины.

Например, для 4-байтового значения (32-битного) мы маскируем с помощью 0xffffffff:

>>> format(-1 & 0xffffffff, "08X")
'FFFFFFFF'
>>> format(1 & 0xffffffff, "08X")
'00000001'
>>> format(123 & 0xffffffff, "08X")
'0000007B'
>>> format(-312367 & 0xffffffff, "08X")
'FFFB3BD1'
person dcoles    schedule 28.08.2015

Модуль struct выполняет преобразования между значениями Python и структурами C, представленными в виде байтовых объектов Python. . Объект упакованных байтов предлагает доступ к отдельным значениям байтов. Это можно использовать для отображения базового (C) целочисленного представления.

>>> packed = struct.pack('>i',i) # big-endian integer
>>> type(packed)
<class 'bytes'>
>>> packed
b'\xff\xfb;\xd1'
>>> "%X%X%X%X" % tuple(packed)
'FFFB3BD1'
>>> 
person gimel    schedule 13.07.2010

person    schedule
comment
Для 123 разве 16-битное представление дополнения до 2 не равно 0x007b? 0xff85 будет для -123. - person dcoles; 28.08.2015
comment
@dcoles, нет, сумма 123 и ее дополнение до 2 должны быть равны 0 (бит переноса/переполнения отбрасывается). Не имеет значения, хотите ли вы рассматривать 0xff85 как знаковое или беззнаковое. - person John La Rooy; 28.08.2015
comment
Я согласен с тем, что дополнение 2 (операция с двоичными числами) 0x007b равно 0xff85, но я полагаю, что вопрос был о представлении числа со знаком дополнения 2. - person dcoles; 28.08.2015
comment
@dcoles, а. Думаю, я понимаю, о чем вы говорите. Возможно, будет понятнее, если я сделаю x = -123 - person John La Rooy; 29.08.2015