将负值转换为bytearray

时间:2017-08-10 13:36:04

标签: python python-2.7

我正在测试与Python的串行通信,所以我需要将十六进制字符串转换为字节数组。 但是现在我遇到了将负值表示为十六进制表示法的问题。 比方说,我想将十六进制16(十进制100)转换为bytearray;我会用:

myvalue = bytearray.fromhex("16")

但如果我尝试转换-100

myvalue = bytearray.fromhex("-16")

我得到一个 ValueError:在fromhex()arg中找到位于0的非十六进制数字

具体来说,我必须使用串行API通过usb控制电机旋转。根据文档,我可以使用2byte有符号值指定介于-32768和32767之间的角度。

那么,我该怎么办?

1 个答案:

答案 0 :(得分:1)

当您使用bytearray.fromhex("16")时,您使用十六进制表示法来描述您想要的位模式。在一个位模式中,我们称之为 sign 的纯粹是传统的。因此,正确的表示取决于接收进程是否期望有符号字节(可以表示数字-128到127)。如果是,那么它可能会期待二进制补码表示。二进制补码的配方是“翻转位并加1”。因此,要表示-1,请从二进制0000 0001开始,翻转位以获取1111 1110并添加1以获取1111 11110xFF)。同样,要表示-100,请从二进制0110 01000x64,十进制100)开始,翻转位以获取1001 1011并添加1以获取1001 1100({{ 1}})。

正如您所看到的,我将您的等同0x9C与十进制100有问题。在我的书中,0x16是十进制22:0x16是十进制100.如上所示, 0x64的两个补码是0x64。从0x9C到达那里:

-100

在Python中比在翻转位和添加1更容易。

要表示2字节的负数,您需要做类似的事情。要获得7位整数(最多127)的二进制补码,则减去256.要得到15位整数(最多32,767)的二进制补码,请从65,536减去( 32,767)

表示负角度10,000:这个65,536 - 10,000 = 55,536。其位模式为>>> bytearray([256-100]) bytearray(b'\x9c') ,即0xD8F0

与负字节一样,接收器是否将该位模式解释为55,536或-10,000。您正在与之交谈的设备需要一个带符号的16位整数(范围-32768..32767),因此可以依赖它将位模式bytearray([0xd8, 0xf0])解释为-10,000而不是55,536。没有值的冲突,因为55,536超出了允许的范围。