web-dev-qa-db-ja.com

pythonで負の整数値を16進数に変換する方法

私はpython 2.6を使用しています

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

>>> hex(199703103)
'0xbe73a3f'

正と負の値は同じですか?

Calcを使用すると、値はFFFFFFFFF418C5C1

25
nic nic

Pythonの整数は、任意に大きくなる可能性があります。 raw two's-complement を希望どおりに計算するには、目的のビット幅を指定する必要があります。あなたの例では、64ビットの2の補数で_-199703103_を示していますが、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
_
48
NPE

Python整数は任意に大きいため、値をマスクして、2の補数表現に必要なビット数に変換を制限する必要があります。

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

Pythonは、単純なhex(-199703103)を負の16進値(_-0xbe73a3f_)として表示します。これは、2の補数表現の前に、任意の精度の数値に対して無限数のFがあるためです。マスク値(2 ** 32-1 == 0xFFFFFFFF)はこれを制限します。

_FFF...FFFFFFFFFFFFFFFFFFFFFFFFF418c5c1
&                             FFFFFFFF
--------------------------------------
                              F418c5c1
_
13
Mark Tolonen

Marks answer に追加します。別の出力形式が必要な場合は、

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