[英]16 bit hex into 14 bit signed int python?
I get a 16 bit Hex number (so 4 digits) from a sensor and want to convert it into a signed integer so I can actually use it. 我从传感器获取一个16位十六进制数字(即4位数字),并希望将其转换为有符号整数,以便我可以实际使用它。 There are plenty of codes on the internet that get the job done, but with this sensor it is a bit more arkward.
互联网上有很多代码可以完成工作,但是有了这个传感器,它就显得有些尴尬了。
In fact, the number has only 14 bit, the first two (from the left) are irrelevant. 实际上,数字只有14位,前两位(从左开始)是无关紧要的。 I tried to do it (in Python 3) but failed pretty hard.
我试图做到这一点(在Python 3中),但失败相当艰巨。 Any suggestions how to "cut" the first two digits of the number and then make the rest a signed integer?
有什么建议如何“削减”数字的前两位数字,然后使其余数字成为有符号整数? The Datasheet says, that E002 should be -8190 ane 1FFE should be +8190.
数据表说,E002应该是-8190,而1FFE应该是+8190。
Thanks a lot! 非常感谢!
Let's define a conversion function: 让我们定义一个转换函数:
>>> def f(x):
... r = int(x, 16)
... return r if r < 2**15 else r - 2**16
...
Now, let's test the function against the values that the datahsheet provided: 现在,让我们对照数据表提供的值测试该函数:
>>> f('1FFE')
8190
>>> f('E002')
-8190
The usual convention for signed numbers is that a number is negative if the high bit is set and positive if it isn't. 对于带符号的数字,通常的约定是:如果设置了高位,则数字为负;如果未设置高位,则为正。 Following this convention, '0000' is zero and 'FFFF' is -1.
按照该约定,“ 0000”为零,“ FFFF”为-1。 The issue is that
int
assumes that a number is positive and we have to correct for that: 问题是
int
假设数字是正数,我们必须对此进行更正:
For any number equal to or less than 0x7FFF
, then high bit is unset and the number is positive. 对于等于或小于
0x7FFF
任何数字,则高位未设置并且该数字为正。 Thus we return r=int(x,16)
if r<2**15. 因此
r=int(x,16)
如果r <2 ** 15 r=int(x,16)
则返回r=int(x,16)
。
For any number r-int(x,16)
that is equal to or greater than 0x8000
, we return r - 2**16
. 对于等于或大于
0x8000
任何数字r-int(x,16)
,我们返回r - 2**16
。
While your sensor may only produce 14-bin data, the manufacturer is following the standard convention for 16-bit integers. 虽然您的传感器只能产生14档数据,但制造商正在遵循16位整数的标准约定。
Instead of converting x
to r
and testing the value of r
, we can directly test whether the high bit in x
is set: 相反转换的
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
Let's suppose that the manufacturer is not following standard conventions and that the upper 2-bits are unreliable. 让我们假设制造商未遵循标准约定,并且高2位不可靠。 In this case, we can use modulo,
%
, to remove them and, after adjusting the other constants as appropriate for 14-bit integers, we have: 在这种情况下,我们可以使用
%
取模,然后将它们调整为适合于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
There is a general algorithm for sign-extending a two's-complement integer value val
whose number of bits is nbits
(so that the top-most of those bits is the sign bit). 存在一种通用的算法,用于对位数为
nbits
位的二进制补码整数值val
进行符号扩展(因此,这些位的最高位是符号位)。
That algorithm is: 该算法是:
Expressing this algorithm in Python produces: 在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))
which when run shows the desired results: 运行时显示出预期的结果:
sext(0xe002, 14) = -8190
sext(0x1ffe, 14) = 8190
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.