将bitstring转换为32位有符号整数会产生错误的结果

时间:2017-02-11 21:04:50

标签: python python-2.7 bits

我正在尝试解决this网站上的挑战。我有一切正确,除了我不能正确地将位串转换为其32位有符号整数表示。

例如,我有这个位串:

block = '10101010001000101110101000101110'

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

当我这样做时,它给出了基数为10的数字。它只是将它转换为基数10:

int(block, 2) #yields 2854414894

我已经尝试排除第一位并转换剩余的31位长度位串,然后检查第一位以判断这是否为负数:

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

但正确的答案是-1440552402。我应该对此bitstring执行什么操作才能获得此整数?如果系统的字节顺序是小端或大端,是否相关?我的系统是小端。

3 个答案:

答案 0 :(得分:3)

在python中,整数没有大小,所以你永远不会得到高位1位的负值。

To" emulate" 32位行为只是这样做,因为您的2854414894值是> 2**31-1又名0x7FFFFFFF

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

你会得到

-1440552402

答案 1 :(得分:3)

你是正确的,高位确定符号,但它不是一个简单的标志。相反,负数的整个特征是反转的。这是一个正数1(8位):

00000001

这是否定的1:

11111111

结果是加法和减法“环绕”。所以4 - 1将是:

0100 - 0001 = 0011

因此0 - 1与1_0000_0000相同 - 1.“借用”只是偏离整数的顶部。

“否定”数字的一般方法是“反转位,加1”。这有两种方式,所以你可以从积极到消极,然后回来。

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

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

print(asnum)

答案 2 :(得分:2)

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

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

首先,您将数字解释为无符号数字,但是当您注意到符号位已设置(> = 2 ^ 31)时,您减去2 ^ 32以获得负数