如何在Python中以二进制补码形式打印有符号整数的十六进制表示?

10

我有一个负整数(4个字节),我想要得到它的二进制补码形式的十六进制表示。

>>> i = int("-312367")
>>> "{0}".format(i)
'-312367'
>>> "{0:x}".format(i)
'-4c42f'

但是我想看到 "FF..."


它的二进制补码表示的十六进制形式是什么?这有什么帮助吗? - Konrad
请查看以下相关问题的答案,看看是否符合您的需求:https://dev59.com/qHI-5IYBdhLWcg3w8NSB#1605553 - sarnold
Konrad,也许他正在准备一种工具来向他的学生展示如何完成。或者他很好奇。或者他有一个API要遵循。或者他的朋友打赌说Perl可以做得更好,然后输了一箱啤酒。 - sarnold
是的,bitstrings的十六进制属性似乎也返回了我所需的内容。谢谢。 - none
@Konrad 这对于调试二进制文件有时是很有用的。 - Quantum7
显示剩余2条评论
6个回答

6
这里有一种方法(针对16位数字):
>>> x=-123
>>> hex(((abs(x) ^ 0xffff) + 1) & 0xffff)
'0xff85'

(虽然可能不是最优雅的方式)


2
这对正数无效。如果x=1,则会得到0xffff(16位二进制补码中的-1),而不是0x0001 - dcoles
给出的例子是一个负整数,但问题是“如何打印以二进制补码表示的有符号整数...”。如果这个答案只适用于负的有符号整数,那么可能会令人困惑。 - dcoles

5
>>> x = -123
>>> bits = 16
>>> hex((1 << bits) + x)
'0xff85'
>>> bits = 32
>>> hex((1 << bits) + x)
'0xffffff85'

对于123来说,16位2的补码表示不是0x007b吗?0xff85则是-123的表示。 - dcoles
@dcoles,123与其补数的和应该为0(进位/溢出位被舍弃)。无论您想将0xff85视为有符号还是无符号都没有关系。 - John La Rooy
我同意0x007b的二进制补码是0xff85,但我认为问题是关于二进制补码有符号数表示的。 - dcoles
1
@dcoles,啊。我想我明白你的意思了。如果我把x=-123写出来可能会更清晰。 - John La Rooy

5
使用 bitstring 模块:
>>> bitstring.BitArray('int:32=-312367').hex
'0xfffb3bd1'

3
简单
>>> hex((-4) & 0xFF)
'0xfc'

2

要将整数视为二进制值,您需要使用所需位长的掩码进行按位与操作。

例如,对于4字节值(32位),我们使用掩码0xffffffff:

>>> format(-1 & 0xffffffff, "08X")
'FFFFFFFF'
>>> format(1 & 0xffffffff, "08X")
'00000001'
>>> format(123 & 0xffffffff, "08X")
'0000007B'
>>> format(-312367 & 0xffffffff, "08X")
'FFFB3BD1'

0

struct 模块执行 Python 值和表示为 Python 字节对象的 C 结构之间的转换。打包的字节对象提供对单个字节值的访问。 这可用于显示底层 (C) 整数表示。

>>> packed = struct.pack('>i',i) # big-endian integer
>>> type(packed)
<class 'bytes'>
>>> packed
b'\xff\xfb;\xd1'
>>> "%X%X%X%X" % tuple(packed)
'FFFB3BD1'
>>> 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接