簡體   English   中英

將16位十六進制轉換為14位帶符號的int python?

[英]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位整數的標准約定。

另類

相反轉換的xr和測試的價值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進行符號擴展(因此,這些位的最高位是符號位)。

該算法是:

  1. 將值視為非負數,並在需要時屏蔽掉其他位
  2. 反轉符號位,仍將結果視為非負數
  3. 減去被認為是非負數的符號位的數值,從而產生一個符號數。

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM