如何在python中将负整数值转换为十六进制

Posted

技术标签:

【中文标题】如何在python中将负整数值转换为十六进制【英文标题】:how to convert negative integer value to hex in python 【发布时间】:2011-12-10 23:58:03 【问题描述】:

我使用 python 2.6

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

>>> hex(199703103)
'0xbe73a3f'

正负值一样吗?

当我使用 calc 时,值为FFFFFFFFF418C5C1

【问题讨论】:

【参考方案1】:

Python 的整数可以任意增长。为了以您想要的方式计算原始two's-complement,您需要指定所需的位宽。您的示例以 64 位二进制补码显示 -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

【讨论】:

能否解释一下添加(1&lt;&lt;64) 时发生的情况?为什么需要这样做? @jathanism,(1&lt;&lt;64) 的值比 64 位整数大一。将其添加到负数将使其变为正数,只要负数适合 64 位。如果原始数字是正数,% 将撤消添加的效果。 我相信这个实现有一个bug:tohex(-129,8)返回0x7f,这是不可能的,因为8位有符号整数只能存储来自(-1)*(2 ^7)= -128 到 2^7 - 1 = 127。因此该函数应在返回之前检查 val 是否在此范围内,如果不在此范围内,则引发异常(或其他情况)。我认为这可以使代码更健壮:)【参考方案2】:

因为 Python 整数是任意大的,所以您必须屏蔽这些值以将转换限制为您想要的 2s 补码表示的位数。

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

Python 将 hex(-199703103) 的简单情况显示为负十六进制值 (-0xbe73a3f),因为 2s 补码表示在其前面将有无限数量的 Fs 用于任意精度数。掩码值 (2**32-1 == 0xFFFFFFFF) 限制了这一点:

FFF...FFFFFFFFFFFFFFFFFFFFFFFFF418c5c1
&                             FFFFFFFF
--------------------------------------
                              F418c5c1

【讨论】:

虽然简洁,但与位操作相比,升权不是成本高吗? @swdev, py -m timeit "2**32-1" -> 每个循环 0.0235 微秒,py -m timeit "2&lt;&lt;32-1" -> 每个循环 0.0235 微秒。不要假设。如果您关心,请务必测量 :) Python 字节编译器很可能会生成相同的加载常量。 哎呀,让(1&lt;&lt;32)-1...但你明白了...也更容易犯错误。我检查了dis 模块,Python 只生成了一个常量。 如果您担心时间问题,您也可以使用常量0xFFFFFFFF 来代替2**32-1 32 位和0xFFFFFFFFFFFFFFFF 64 位。或mask_32bit=(2**32-1) 这样您就不必每次都进行计算,只需一次。 @busfault 每个评论上面的速度没有什么不同。 Python 在生成字节码时计算一次常量。无需“优化”。【参考方案3】:

添加到Marks answer,如果您想要不同的输出格式,请使用

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

【讨论】:

【参考方案4】:

对于那些想要正数前导零的人,试试这个:

val = 42
nbits = 16
':04X'.format(val & ((1 << nbits)-1))

感谢@tm1 的启发!

【讨论】:

':0X'.format(val &amp; ((1 &lt;&lt; nbits)-1), int((nbits+3)/4)) 将正确设置宽度。

以上是关于如何在python中将负整数值转换为十六进制的主要内容,如果未能解决你的问题,请参考以下文章

如何在颤动中将十六进制颜色代码解析为它们各自的整数值

如何在 Python 中将十六进制转换为十进制? [复制]

你如何在Python中将十六进制转换为三元组?

在 C++ 中将十六进制字符转换为 int

如何在 Python 中将字符串转换为十六进制整数?

在 Python 中将十六进制转换为 RGB 值