将二进制数据转换为有符号整数
我读取了一个二进制文件,得到了一个字符数组。当我把两个字节转换成一个整数时,我用的是 256*ord(p1) + ord(p0)
这个方法。这个方法对正整数有效,但当我得到负数时就不行了。我知道这和最高位的第一个字节有关,但我试了很多方法都没成功。
我还了解到有一个叫 struct
的东西,读完之后我写出了以下代码:
import struct
p1 = chr(231)
p0 = chr(174)
a = struct.unpack('h',p0+p1)
print str(a)
a
的值变成了 -6226,如果我把 p0
和 p1
交换一下,得到的值是 -20761。
其实 a
应该是 -2。
6 个回答
0
顺便说一下,其实你可以不使用 struct
来实现这个。你原来的公式可以继续用,但如果结果大于 32767,就要减去 65536。(或者如果高位字节大于 127,这两者是一样的。)可以查一下二进制补码,这就是现代计算机表示负数的方式。
p1 = chr(231)
p0 = chr(174)
a = 256 * ord(p1) + ord(p0) - (65536 if ord(p1) > 127 else 0)
这样你就能得到正确的答案 -6226。(正确的答案 不是 -2。)
1
一般来说,当你使用结构体(struct)时,你的格式字符串应该以某种对齐方式的标识符开始。这个默认的对齐方式在不同的机器上可能会有所不同。
所以,正确的结果是
>>> struct.unpack('!h',p0+p1)[0]
-20761
-2在大端(big endian)表示法中的样子是:
1111 1111 1111 1110 # binary
255 254 # decimal bytes
f f f e # hexadecimal bytes
你可以很简单地通过加上2来验证这个结果,最后会得到0。
2
-2这个值对于你指定的那些值来说是不正确的,而且字节顺序是很重要的。struct
使用>
表示大端字节序(最重要的字节在前面),而使用<
表示小端字节序(最不重要的字节在前面):
>>> import struct
>>> struct.pack('>h',-2)
'\xff\xfe'
>>> struct.pack('<h',-2)
'\xfe\xff'
>>> p1=chr(254) # 0xFE
>>> p0=chr(255) # 0xFF
>>> struct.unpack('<h',p1+p0)[0]
-2
>>> struct.unpack('>h',p0+p1)[0]
-2