将十六进制字符串转换为Python中的有符号整数

24 投票
5 回答
61686 浏览
提问于 2025-04-16 21:44

我想知道怎么把一个十六进制字符串转换成Python 3中的带符号整数。

我想到的办法是

h = '9DA92DAB'
b = bytes(h, 'utf-8')
ba = binascii.a2b_hex(b)
print(int.from_bytes(ba, byteorder='big', signed=True))

有没有更简单的方法?无符号整数的转换要简单得多:int(h, 16)

顺便说一下,这个问题的来源是 itunes持久ID - 音乐库XML版本和iTunes十六进制版本

5 个回答

4

这里有一个通用的函数,你可以用它来处理任何大小的十六进制数:

import math

# hex string to signed integer
def htosi(val):
    uintval = int(val,16)
    bits = 4 * (len(val) - 2)
    if uintval >= math.pow(2,bits-1):
        uintval = int(0 - (math.pow(2,bits) - uintval))
    return uintval

使用这个函数的方法如下:

h = str(hex(-5))
h2 = str(hex(-13589))
x = htosi(h)
x2 = htosi(h2)
17
h = '9DA92DAB'
struct.unpack('<i', h.decode('hex'))

对于Python 3(有注释的帮助):

import struct

对于Python 2:

h = '9DA92DAB'
struct.unpack('>i', bytes.fromhex(h))

或者如果是小端格式:

h = '9DA92DAB'
struct.unpack('>i', h.decode('hex'))
53

在n位的二进制补码表示中,各个位的值是这样的:

第0位 = 20
第1位 = 21
第n-2位 = 2n-2
第n-1位 = -2n-1

不过,当我们不考虑符号位(即当它是无符号数时),第n-1位的值是2n-1,这样一来,整个数字就会比实际值高出2n。如果第n-1位被设置为1,就需要从这个数字中减去2n

def twos_complement(hexstr, bits):
    value = int(hexstr, 16)
    if value & (1 << (bits - 1)):
        value -= 1 << bits
    return value

print(twos_complement('FFFE', 16))
print(twos_complement('7FFF', 16))
print(twos_complement('7F', 8))
print(twos_complement('FF', 8))

输出:

-2
32767
127
-1

撰写回答