我有一个十六进制字符串f6befc34e3de2d30
。我想将它转换为签名长,但
x['id'], = struct.unpack('>q', 'f6befc34e3de2d30'.decode('hex'))
给出:
-0b100101000001000000111100101100011100001000011101001011010000
0b1111011010111110111111000011010011100011110111100010110100110000
预期。
谢谢!
答案 0 :(得分:3)
你可以long('f6befc34e3de2d30', 16)
bin(long('f6befc34e3de2d30', 16))
>>> '0b1111011010111110111111000011010011100011110111100010110100110000'
编辑:跟进@Paul Panzer的评论。对于基于ALU硬件的C类型长实现,情况确实如此。你不能有大于2 ^ 63的有符号整数。但是,Python的实现是不同的,并且依赖于大数字的数组表示,以及用于算术运算的Karatsuba算法。这就是为什么这种方法有效。
编辑2 :关注OP问题。没有“第一位作为标志”的问题。在您的问题中,您明确地希望使用Python的long构造,对于该构造,实现不是您期望的那种,它使用的表示与您在C中可能熟悉的表示不同。相反,它将大整数表示为数组。因此,如果您想实现某种第一位逻辑,则必须自己完成。我没有任何文化或经验,所以以下可能会因为有人知道他的东西而完全错误,但仍然让我给你我的看法。
我看到两种方法。在第一个中,您同意您想要使用的最大长度的约定,然后实现ALU所执行的相同类型的逻辑。让我们说,为了论证,我们希望在[-2^127, 2^127-1]
范围内使用长符号。我们可以做以下
MAX_LONG = long('1' + "".join([str(0)]*127), 2)
def parse_nb(s):
# returns the first bit and the significand in the case of a usual
# integer representation
b = bin(long(s, 16))
if len(b) < 130: # deal with the case where the leading zeros are absent
return "0", b[2:]
else:
return b[2], b[3:]
def read_long(s):
# takes an hexadecimal representation of a string, and return
# the corresponding long with the convention stated above
sign, mant = parse_nb(s)
b = "0b" + mant
if sign == "0":
return long(b, 2)
else:
return -MAX_LONG + long(b, 2)
read_long('5')
>>> 5L
# fffffffffffffffffffffffffffffffb is the representation of -5 using the
# usual integer representation, extended to 128 bits integers
read_long("fffffffffffffffffffffffffffffffb")
>>> -5L
对于第二种方法,您不认为存在MAX_LONG,而是第一位始终是符号位。然后你必须修改上面的parse_nb
方法。我把它留作练习:)。