2014-10-29 69 views
3

下面的a和b(十六進制)表示二進制補碼帶符號的二進制數。 例如:Python中十六進制數的二進制補碼

a = 0x17c7cc6e 
b = 0xc158a854 

現在我想知道一個& B在底部的符號表示10對不起,我低水平程序員,新的Python;感到非常愚蠢的問這個問題。我不在乎額外的圖書館,但答案應該簡單而直接。背景:一個&b是從UDP數據包提取數據。我無法控制格式。所以請不要給我一個答案,假設我可以事先更改這些變體的格式。

我已經轉換一個& b代入本以下:

aBinary = bin(int(a, 16))[2:].zfill(32) => 00010111110001111100110001101110 => 398969966 
bBinary = bin(int(b, 16))[2:].zfill(32) => 11000001010110001010100001010100 => -1051154348 

我試圖做這樣的事情(不工作):

if aBinary[1:2] == 1: 
aBinary = ~aBinary + int(1, 2) 

什麼是正確的在Python中做到這一點?

回答

2

您必須至少知道數據的寬度。例如,0xc158a854有8個十六進制數字,所以它必須至少有32位寬;它似乎是一個無符號的32位值。我們可以使用一些位操作對其進行處理:

In [232]: b = 0xc158a854 

In [233]: if b >= 1<<31: b -= 1<<32 

In [234]: b 
Out[234]: -1051154348L 

將L這裏標誌着Python的2已切換到加工值作爲長;它通常並不重要,但在這種情況下,表明我一直在使用公共int範圍之外的值來處理此安裝。從二進制結構(如UDP數據包)提取數據的工具是struct.unpack;如果你只是告訴它你的價值是擺在首位簽約時,會產生正確的值:

In [240]: s = '\xc1\x58\xa8\x54' 

In [241]: import struct 

In [242]: struct.unpack('>i', s) 
Out[242]: (-1051154348,) 

,它假定二進制補碼錶示;補碼(例如UDP中使用的校驗和),符號和幅度或IEEE 754浮點數是一些不太常用的編碼編碼。

+0

謝謝!第一種方法效果很好,它是一個沒有庫+1的單線程。 – Nimjox 2014-10-29 23:02:51

2
>>> import numpy 
>>> numpy.int32(0xc158a854) 
-1051154348 
2

在Python中執行此操作的好方法是使用按位運算。例如,對於32位值:

def s32(value): 
    return -(value & 0x80000000) | (value & 0x7fffffff) 

將此應用於自己的價值觀:

>>> s32(a) 
398969966 
>>> s32(b) 
-1051154348 

什麼這個函數是符號擴展的值,所以它的正確與正確的符號和數值解釋。

Python是有點棘手,因爲它使用任意的精度整數,所以負數被視爲有無限的前導1位系列。例如:

>>> bin(-42 & 0xff) 
'0b11010110' 
>>> bin(-42 & 0xffff) 
'0b1111111111010110' 
>>> bin(-42 & 0xffffffff) 
'0b11111111111111111111111111010110' 
相關問題