将二进制数据转换为有符号整数

时间:2011-10-18 16:37:53

标签: python

我读了一个二进制文件并得到一个包含字符的数组。将两个字节转换为整数时,我会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,如果我交换p0p1,我会得到-20761。

a应该是-2

6 个答案:

答案 0 :(得分:2)

对于您指定的值,

-2不正确,字节顺序很重要。 struct使用>表示big-endian(最重要的字节优先)和<表示little-endian(最不重要的字节优先):

>>> 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

答案 1 :(得分:1)

通常,在使用struct时,您的格式字符串应以alignment specifiers之一开头。默认的本机版本因机器而异。

因此,正确的结果是

>>> struct.unpack('!h',p0+p1)[0]
-20761

endian中-2的表示是:

1111 1111 1111 1110 # binary
  255        254    # decimal bytes
  f   f    f    e   # hexadecimal bytes

您可以通过添加两个来轻松验证,结果为0。

答案 2 :(得分:0)

使用第一种方法(256*ord(p1) + ord(p0)),您可以检查第一位是否为if p1 & 0x80 > 0为1。如果是,那么您使用p1 & 0x7f代替p1,然后否定最终结果。

答案 3 :(得分:0)

如果使用掩码取消负数中的额外1位,原始等式将正常工作:

256*(ord(p0) & 0xff) + (ord(p1) & 0xff)

编辑:我想我可能误解了你的问题。您是否尝试将两个正字节值转换为负整数?这应该有效:

a = 256*ord(p0) + ord(p1)
if a > 32767: # 0x7fff
    a -= 65536 # 0x10000

答案 4 :(得分: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。

答案 5 :(得分:0)

如果要转换文件较大的值,请使用array模块。

对于文件,请知道重要的是文件格式的endianess。不是写或正在阅读它的机器的endianess。

当然,Alex Martelli有the definitive answer