16位十六进制到14位带符号整数python?

16位十六进制到14位带符号整数python?,python,cut,bits,data-conversion,Python,Cut,Bits,Data Conversion,我从一个传感器得到一个16位十六进制数(所以是4位数字),我想把它转换成一个有符号整数,这样我就可以实际使用它了。 互联网上有很多代码可以完成这项工作,但是有了这个传感器,它就有点不可靠了 事实上,数字只有14位,前两位(从左起)是不相关的。 我试着去做(在Python 3中),但是失败了。 有没有建议如何“剪切”数字的前两位,然后使其余的数字成为有符号整数? 数据表上说,E002应为-8190,1FFE应为+8190 非常感谢 有一种通用的符号扩展算法,用于扩展二进制补码整数值val,该整数值

我从一个传感器得到一个16位十六进制数(所以是4位数字),我想把它转换成一个有符号整数,这样我就可以实际使用它了。 互联网上有很多代码可以完成这项工作,但是有了这个传感器,它就有点不可靠了

事实上,数字只有14位,前两位(从左起)是不相关的。 我试着去做(在Python 3中),但是失败了。 有没有建议如何“剪切”数字的前两位,然后使其余的数字成为有符号整数? 数据表上说,E002应为-8190,1FFE应为+8190


非常感谢

有一种通用的符号扩展算法,用于扩展二进制补码整数值
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))
    

    有一种通用的符号扩展算法,用于扩展二进制补码整数值
    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))
    

    让我们定义一个转换函数:

    >>> def f(x):
    ...    r = int(x, 16)
    ...    return r if r < 2**15 else r - 2**16
    ... 
    
    对于有符号数字,通常的约定是,如果设置了高位,则数字为负;如果未设置高位,则数字为正。按照此约定,“0000”为零,“FFFF”为-1。问题是,
    int
    假设一个数字为正,我们必须对此进行更正:


    • 对于等于或小于
      0x7FFF
      的任何数字,则高位未设置,且该数字为正数。因此,我们返回
      r=int(x,16)
      如果r让我们定义一个转换函数:

      >>> def f(x):
      ...    r = int(x, 16)
      ...    return r if r < 2**15 else r - 2**16
      ... 
      
      对于有符号数字,通常的约定是,如果设置了高位,则数字为负;如果未设置高位,则数字为正。按照此约定,“0000”为零,“FFFF”为-1。问题是,
      int
      假设一个数字为正,我们必须对此进行更正:


      • 对于等于或小于
        0x7FFF
        的任何数字,则高位未设置,且该数字为正数。因此,如果旁注:“digit”不是正确的术语,我们返回
        r=int(x,16)
        。这是保留给十进制数(不是十六进制)谢谢你纠正我下沉点!我不是以英语为母语的人,据我所知,我们对不同的数字系统没有不同的术语,所以我没有想到这一点。虽然知道这些很好,但学到一些东西总是很好的;)作为旁注:“数字”不是正确的术语。这是保留给十进制数(不是十六进制)谢谢你纠正我下沉点!我不是以英语为母语的人,据我所知,我们对不同的数字系统没有不同的术语,所以我没有想到这一点。虽然知道这些很好,但学到一些东西总是很好的;)这里您将(至少可能)遇到14位数字的问题是,位0xc000意味着被忽略,因此0xe002是-8190,0x2002也是。如果位14和15是符号位(位13)的副本,则可以将其视为有符号16位2的补码值。@torek True。除了制造商说E002是-8190外,我会担心这一点:换句话说,他们遵循16位整数的标准约定。@torek为了完整性,我刚刚添加了忽略上2位的代码。非常感谢您解决我的问题,也感谢您的解释!这里您将(至少可能)遇到14位数字的问题是,位0xc000意味着被忽略,因此0xe002是-8190,0x2002也是。如果位14和15是符号位(位13)的副本,则可以将其视为有符号16位2的补码值。@torek True。除了制造商说E002是-8190外,我会担心这一点:换句话说,他们遵循16位整数的标准约定。@torek为了完整性,我刚刚添加了忽略上2位的代码。非常感谢您解决我的问题,也感谢您的解释!
        >>> def g(x):
        ...    return int(x, 16) if x[0] in '01234567' else int(x, 16) - 2**16
        ... 
        >>> g('1FFE')
        8190
        >>> g('E002')
        -8190
        
        >>> 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