2011-10-18 142 views
4

我讀取一個二進制文件並獲取一個包含字符的數組。當將兩個字節轉換爲整數時,我做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

回答

0

與第一種方法(256*ord(p1) + ord(p0)),你可以檢查,看是否第一位是1 if p1 & 0x80 > 0。如果是這樣,那麼你會使用p1 & 0x7f而不是p1,然後否定最終結果。

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

0

如果您使用掩碼來取消負數中多餘的1位,您的原始公式將正常工作:

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

編輯:我想我可能誤解了你的問題。你試圖將兩個正值字節值轉換爲一個負整數?這應該工作:

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

由於這些已經是8位數量,屏蔽掉較低的8位不會做任何事情。 – kindall

+0

要屏蔽符號位,您可以使用'&0x7F',否? – 2011-10-18 19:12:18

+0

@ kindall,原始問題談到負數。負數是符號擴展的,所以高位包含「1」而不是「0」,因此掩蓋它們變得必要。我仍然不確定'ord'如何返回一個負數。 –

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

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

如果從一個文件,是大轉換值,可以使用array模塊。

對於一個文件,要知道它是文件格式的重要性。不是機器的永久性,不是寫它就是讀它。

Alex Martelli當然有the definitive answer

相關問題