Я использую питон 2.6
>>> hex(-199703103)
'-0xbe73a3f'
>>> hex(199703103)
'0xbe73a3f'
Положительное и отрицательное значение совпадают?
Когда я использую calc, значение равно FFFFFFFFF418C5C1
.
Я использую питон 2.6
>>> hex(-199703103)
'-0xbe73a3f'
>>> hex(199703103)
'0xbe73a3f'
Положительное и отрицательное значение совпадают?
Когда я использую calc, значение равно FFFFFFFFF418C5C1
.
Целые числа Python могут расти сколь угодно большими. Чтобы вычислить необработанное двойное дополнение так, как вы хотите, вам нужно будет указать желаемую разрядность. В вашем примере показано -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
(1<<64)
? Почему это нужно делать?
- person jathanism; 19.10.2011
(1<<64)
на единицу больше, чем может поместиться в 64-битное целое число. Добавление его к отрицательному числу сделает его положительным, если отрицательное число умещается в 64 бита. Если исходное число было положительным, %
отменит эффект сложения.
- person Mark Ransom; 19.10.2011
Поскольку целые числа Python произвольно велики, вам необходимо маскировать значения, чтобы ограничить преобразование числом битов, которые вы хотите использовать для представления дополнения до 2 с.
>>> 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
py -m timeit "2**32-1"
-> 0,0235 мкс на цикл, py -m timeit "2<<32-1"
-> 0,0235 мкс на цикл. Не предполагай. Всегда измеряйте, если вам не все равно :) Скорее всего, байтовый компилятор Python генерирует ту же константу нагрузки.
- person Mark Tolonen; 08.01.2015
(1<<32)-1
...но ты понял...Также легче ошибиться. И я проверил с модулем dis
, и Python просто генерирует константу.
- person Mark Tolonen; 08.01.2015
2**32-1
просто использовать константу 0xFFFFFFFF
для 32-битной и 0xFFFFFFFFFFFFFFFF
для 64-битной, если вас беспокоит синхронизация. Или mask_32bit=(2**32-1)
, чтобы не каждый раз считать, а только один раз.
- person Tom Myddeltyn; 17.06.2016
Добавляя к Отметки ответа, если вам нужен другой формат вывода, используйте
'{:X}'.format(-199703103 & (2**32-1))