Python中十六进制数的二补

2024-09-28 23:28:58 发布

您现在位置:Python中文网/ 问答频道 /正文

在a和b(十六进制)下面,表示两个补码有符号二进制数。 例如:

a = 0x17c7cc6e
b = 0xc158a854

现在我想知道a&b在基数10中的有符号表示。抱歉,我是一个低级程序员,对python还不熟悉;这么问真是太蠢了。我不在乎额外的图书馆,但答案应该简单明了。背景:a&b是从UDP数据包中提取的数据。我无法控制格式。所以,请不要给我一个答案,假设我可以改变这些变量的格式之前,手。

我已将a&b转换为以下内容:

aBinary = bin(int(a, 16))[2:].zfill(32) => 00010111110001111100110001101110 => 398969966
bBinary = bin(int(b, 16))[2:].zfill(32) => 11000001010110001010100001010100 => -1051154348

我想做这样的事(不起作用):

if aBinary[1:2] == 1:
aBinary = ~aBinary + int(1, 2)

在python中,正确的方法是什么?


Tags: 答案bin图书馆格式二进制符号数据包程序员
3条回答

你至少要知道你的数据的宽度。例如,0xc158a854有8个十六进制数字,因此它的宽度必须至少为32位;它似乎是一个无符号的32位值。我们可以使用一些按位操作来处理它:

In [232]: b = 0xc158a854

In [233]: if b >= 1<<31: b -= 1<<32

In [234]: b
Out[234]: -1051154348L

这里的L表示Python2已经切换为长时间处理该值;这通常并不重要,但在本例中,表示我一直在处理此安装的公共int范围之外的值。从二进制结构(如UDP数据包)中提取数据的工具是struct.unpack;如果您只是告诉它您的值首先是有符号的,那么它将生成正确的值:

In [240]: s = '\xc1\x58\xa8\x54'

In [241]: import struct

In [242]: struct.unpack('>i', s)
Out[242]: (-1051154348,)

这假定两个的补码表示;一个的补码(如UDP中使用的校验和)、符号和幅度或IEEE 754浮点是一些不太常见的数字编码。

>>> import numpy
>>> numpy.int32(0xc158a854)
-1051154348

在Python中,一个很好的方法是使用按位操作。例如,对于32位值:

def s32(value):
    return -(value & 0x80000000) | (value & 0x7fffffff)

将此应用于您的价值观:

>>> s32(a)
398969966
>>> s32(b)
-1051154348

此函数的作用是对值进行符号扩展,以便用正确的符号和值正确解释它。

Python有点棘手,因为它使用任意精度的整数,所以负数被视为一个前导1位的无限序列。例如:

>>> bin(-42 & 0xff)
'0b11010110'
>>> bin(-42 & 0xffff)
'0b1111111111010110'
>>> bin(-42 & 0xffffffff)
'0b11111111111111111111111111010110'

相关问题 更多 >