web-dev-qa-db-fra.com

comment convertir une valeur entière négative en hexa en python

J'utilise Python 2.6

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

>>> hex(199703103)
'0xbe73a3f'

La valeur positive et négative sont les mêmes?

Lorsque j'utilise calc, la valeur est FFFFFFFFF418C5C1.

20
nic nic

Les entiers de Python peuvent devenir arbitrairement grands. Afin de calculer le brut complément à deux comme vous le souhaitez, vous devez spécifier la largeur de bits souhaitée. Votre exemple montre -199703103 en complément à deux bits 64 bits, mais il aurait tout aussi bien pu être en 32 bits ou en 128 bits, ce qui donnerait un nombre différent de 0xf au début.

hex() ne fait pas ça. Je suggère ce qui suit comme alternative:

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

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

Cela imprime:

0xfffffffff418c5c1L
0xbe73a3fL
39
NPE

Etant donné que les entiers Python sont arbitrairement grands, vous devez masquer les valeurs pour limiter la conversion au nombre de bits souhaité pour la représentation du complément à 2.

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

Python affiche le cas simple de hex(-199703103) sous la forme d'une valeur hexagonale négative (-0xbe73a3f) car la représentation du complément à 2s aurait un nombre infini de F devant lui pour un nombre de précision arbitraire. La valeur de masque (2 ** 32-1 == 0xFFFFFFFF) limite ceci:

FFF...FFFFFFFFFFFFFFFFFFFFFFFFF418c5c1
&                             FFFFFFFF
--------------------------------------
                              F418c5c1
9
Mark Tolonen

Ajout à Les marques répondent , si vous voulez un format de sortie différent,

'{:X}'.format(-199703103 & (2**32-1))
1
tm1