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