2017-02-11 46 views
0

我正试图解决this站点上的问题。除了无法正确地将位串转换为其32位有符号整数表示形式外,我的一切都正确。将bitstring转换为32位有符号整数会产生错误的结果

例如,我有这样的比特串:我部分从学校请记住,第一位为符号位:

block = '10101010001000101110101000101110' 

我这个位串转换为32位有符号整数的自己的路。如果它是1,我们有负数,反之亦然。

我这样做的时候,它给了我它只是将它转换为10进制以10为底数的数字:即检查后

int(block, 2) #yields 2854414894 

我试图排除的第一位,并转换其余31位串的长度,第一位来决定这是否是负数或不是:

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

但正确答案是-1440552402。我应该怎么做这个bitstring得到这个整数?如果系统的字节顺序是小端或大端,它是否相关?我的系统是小端。

+0

到http://stackoverflow.com/questions/1375897/how-to-get-the-signed-integer-value-of-a-long-in-python类似 –

回答

2

你说得对,高位确定符号,但它不是一个简单的标志。相反,负数的整个特征是倒置的。这是一个正数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) 
+0

它解决了我的问题。谢谢。但是,为什么我们异或'asnum'?你能解释一下吗? – Bora

+0

用FFFF(全部1位)对数字进行异或将数据反转。 1变为0,0变为1. –

+0

哦,我明白了。它是补充。难道我们只是使用'〜'运算符来做这件事? – Bora

3

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

要 “效仿” 32位行为,只是这样做,因为你的2854414894值>2**31-1又名0x7FFFFFFF

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

你会得到

-1440552402 
2

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

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

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

相关问题