将位字符串转换为32位带符号整数会产生错误的结果



我正在努力解决这个网站上的一个挑战。除了无法正确地将位字符串转换为其32位有符号整数表示外,我的一切都是正确的。

例如,我有一个比特串:

block = '10101010001000101110101000101110'

我自己将这个比特串转换为32位有符号整数的方法:我部分记得学校里的第一位是符号位。如果是1,我们有负数,反之亦然。

当我这样做的时候,它会给我以10为基数的数字。它只是将其转换为基数10:

int(block, 2) #yields 2854414894

我尝试排除第一个比特并转换剩余的31长度的比特串,之后检查第一个比特以决定这是否是负数:

int(block[1:32], 2) #yields 706931246

但正确答案是-1440552402。我应该对这个位字符串做什么操作才能得到这个整数?系统的字节顺序是小端序还是大端序,这是否相关?我的系统是小端序。

在python中,整数没有大小,因此您永远不会得到高阶1位的负值。

要"模拟"32位行为,只需执行此操作,因为您的2854414894值是>2**31-1,也就是0x7FFFFFFF:

print(int(block[1:32], 2)-2**31)

你会得到

-1440552402

您说得对,高位决定符号,但它不是一个简单的标志。相反,负数的整个特征是颠倒的。这是一个正数1(8位):

00000001

这是一个负1:

11111111

结果是加法和减法"回绕"。所以4-1应该是:

0100 - 0001 = 0011

因此0-1与1_0000_0000-1相同。"借位"刚好偏离整数的顶部。

"求反"一个数字的一般方法是"反转位,加1"。这是双向的,所以你可以从积极到消极,然后再回来。

在您的情况下,使用前导"1"来检测是否需要否定,然后转换为int,然后可能执行否定步骤。然而,请注意,因为python的int不是固定宽度值,所以有一个单独的内部标志(pythonint不是"32位"数字,它是一个任意精度的整数,动态分配的表示形式以某种方式存储,而不是简单的2的补码)。

block = '10101010001000101110101000101110'
asnum = int(block, 2)
if block[0] == '1':
asnum ^= 0xFFFFFFFF
asnum += 1
asnum = -asnum
print(asnum)

您应该检查输入值何时超出32位有符号整数的正范围:

res = int(block, 2)
if res >= 2**31:
res -= 2**32

因此,首先您将该数字解释为一个无符号数字,但当您注意到符号位已设置(>=2^31)时,您减去2^32,得到负数。

最新更新