我从传感器获得一个16位十六进制数(所以4位数),并希望将其转换为有符号整数,以便我可以实际使用它。 互联网上有很多代码可以完成工作,但是使用这个传感器有点笨拙。
实际上,这个数字只有14位,前两位(左起)是无关紧要的。 我试图这样做(在Python 3中)但很难失败。 任何建议如何" cut"数字的前两位数,然后使其余的有符号整数? 数据表说,E002应为-8190,1FFE应为+8190。
非常感谢!
答案 0 :(得分:2)
让我们定义一个转换函数:
>>> def f(x):
... r = int(x, 16)
... return r if r < 2**15 else r - 2**16
...
现在,让我们根据datahsheet提供的值测试函数:
>>> f('1FFE')
8190
>>> f('E002')
-8190
有符号数字的通常惯例是,如果设置高位,则数字为负数,如果不设置则为正数。遵循此约定,'0000'为零,'FFFF'为-1。问题是int
假设一个数字是正数,我们必须纠正:
对于任何等于或小于0x7FFF
的数字,则取消设置高位且数字为正。因此,如果r&lt; 2 ** 15。
r=int(x,16)
对于任何等于或大于r-int(x,16)
的{{1}},我们都会返回0x8000
。
虽然您的传感器可能只生成14位数据,但制造商遵循16位整数的标准惯例。
我们可以直接测试r - 2**16
中的高位是否设置,而不是将x
转换为r
并测试r
的值:
x
假设制造商没有遵循标准惯例,并且高2位是不可靠的。在这种情况下,我们可以使用modulo >>> def g(x):
... return int(x, 16) if x[0] in '01234567' else int(x, 16) - 2**16
...
>>> g('1FFE')
8190
>>> g('E002')
-8190
来删除它们,并在调整了适合14位整数的其他常量后,我们有:
%
答案 1 :(得分:1)
有一种通用算法用于对2位补码整数值val
进行符号扩展,其位数为nbits
(因此这些位的最顶部是符号位)。
该算法是:
在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