[英]16 bit hex into 14 bit signed int python?
我從傳感器獲取一個16位十六進制數字(即4位數字),並希望將其轉換為有符號整數,以便我可以實際使用它。 互聯網上有很多代碼可以完成工作,但是有了這個傳感器,它就顯得有些尷尬了。
實際上,數字只有14位,前兩位(從左開始)是無關緊要的。 我試圖做到這一點(在Python 3中),但失敗相當艱巨。 有什么建議如何“削減”數字的前兩位數字,然后使其余數字成為有符號整數? 數據表說,E002應該是-8190,而1FFE應該是+8190。
非常感謝!
讓我們定義一個轉換函數:
>>> def f(x):
... r = int(x, 16)
... return r if r < 2**15 else r - 2**16
...
現在,讓我們對照數據表提供的值測試該函數:
>>> f('1FFE')
8190
>>> f('E002')
-8190
對於帶符號的數字,通常的約定是:如果設置了高位,則數字為負;如果未設置高位,則為正。 按照該約定,“ 0000”為零,“ FFFF”為-1。 問題是int
假設數字是正數,我們必須對此進行更正:
對於等於或小於0x7FFF
任何數字,則高位未設置並且該數字為正。 因此r=int(x,16)
如果r <2 ** 15 r=int(x,16)
則返回r=int(x,16)
。
對於等於或大於0x8000
任何數字r-int(x,16)
,我們返回r - 2**16
。
雖然您的傳感器只能產生14檔數據,但制造商正在遵循16位整數的標准約定。
相反轉換的x
到r
和測試的價值r
我們可以直接測試在高比特是否x
設置:
>>> def g(x):
... return int(x, 16) if x[0] in '01234567' else int(x, 16) - 2**16
...
>>> g('1FFE')
8190
>>> g('E002')
-8190
讓我們假設制造商未遵循標准約定,並且高2位不可靠。 在這種情況下,我們可以使用%
取模,然后將它們調整為適合於14位整數的其他常量,然后得到:
>>> def h(x):
... r = int(x, 16) % 2**14
... return r if r < 2**13 else r - 2**14
...
>>> h('1FFE')
8190
>>> h('E002')
-8190
存在一種通用的算法,用於對位數為nbits
位的二進制補碼整數值val
進行符號擴展(因此,這些位的最高位是符號位)。
該算法是:
在Python中表達此算法會產生:
from __future__ import print_function
def sext(val, nbits):
assert nbits > 0
signbit = 1 << (nbits - 1)
mask = (1 << nbits) - 1
return ((val & mask) ^ signbit) - signbit
if __name__ == '__main__':
print('sext(0xe002, 14) =', sext(0xe002, 14))
print('sext(0x1ffe, 14) =', sext(0x1ffe, 14))
運行時顯示出預期的結果:
sext(0xe002, 14) = -8190
sext(0x1ffe, 14) = 8190
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.