简体   繁体   English

如何在 Python 中将整数的两个字节转换回整数?

[英]How can I convert two bytes of an integer back into an integer in Python?

I am currently using an Arduino that's outputting some integers (int) through Serial (using pySerial ) to a Python script that I'm writing for the Arduino to communicate with X-Plane , a flight simulation program.我目前正在使用一个Arduino ,它通过 Serial(使用pySerial )将一些整数(int)输出到我正在编写的 Python 脚本,以便ArduinoX-Plane进行通信,这是一个飞行模拟程序。

I managed to separate the original into two bytes so that I could send it over to the script, but I'm having a little trouble reconstructing the original integer.我设法将原始数据分成两个字节,以便将其发送给脚本,但是在重建原始整数时遇到了一些麻烦。

I tried using basic bitwise operators (<<, >> etc.) as I would have done in a C++like program, but it does not seem to be working.我尝试使用基本的按位运算符(<<、>> 等),就像我在类似 C++ 的程序中所做的那样,但它似乎不起作用。

I suspect it has to do with data types.我怀疑这与数据类型有关。 I may be using integers with bytes in the same operations, but I can't really tell which type each variable holds, since you don't really declare variables in Python, as far as I know (I'm very new to Python).我可能在相同的操作中使用带有字节的整数,但我无法确定每个变量包含哪种类型,因为据我所知,你并没有真正在 Python 中声明变量(我对 Python 很陌生) .

self.pot=self.myline[2]<<8
self.pot|=self.myline[3]

You can use the struct module to convert between integers and representation as bytes.您可以使用struct模块在整数和字节表示之间进行转换。 In your case, to convert from a Python integer to two bytes and back, you'd use:在您的情况下,要将 Python 整数转换为两个字节并返回,您可以使用:

>>> import struct
>>> struct.pack('>H', 12345)
'09'
>>> struct.unpack('>H', '09')
(12345,)

The first argument to struct.pack and struct.unpack represent how you want you data to be formatted. struct.packstruct.unpack的第一个参数表示您希望如何格式化数据。 Here, I ask for it to be in big-ending mode by using the > prefix (you can use < for little-endian, or = for native) and then I say there is a single unsigned short (16-bits integer) represented by the H .在这里,我通过使用>前缀要求它处于大结尾模式(你可以使用<表示小端,或=表示本机),然后我说有一个无符号短(16 位整数)表示由H

Other possibilities are b for a signed byte, B for an unsigned byte, h for a signed short (16-bits), i for a signed 32-bits integer, I for an unsigned 32-bits integer.其他可能性是b表示有符号字节, B表示无符号字节, h表示有符号短整型(16 位), i表示有符号 32 位整数, I表示无符号 32 位整数。 You can get the complete list by looking at the documentation of the struct module.您可以通过查看struct模块的文档来获取完整列表。

What you have seems basically like it should work, assuming the data stored in myline has the high byte first:你所拥有的看起来基本上应该可以工作,假设存储在myline的数据myline具有高字节:

myline = [0, 1, 2, 3]
pot = myline[2]<<8 | myline[3]

print 'pot: {:d}, 0x{:04x}'.format(pot, pot)  # outputs "pot: 515, 0x0203"

Otherwise, if it's low-byte first you'd need to do the opposite way:否则,如果首先是低字节,则需要以相反的方式执行:

myline = [0, 1, 2, 3]
pot = myline[3]<<8 | myline[2]

print 'pot: {:d}, 0x{:04x}'.format(pot, pot)  # outputs "pot: 770, 0x0302"

例如,使用大端编码:

int.from_bytes(my_bytes, byteorder='big')

This totally works:这完全有效:

long = 500
first = long & 0xff  #244
second = long >> 8  #1
result = (second << 8) + first #500

If you are not sure of types in 'myline' please check Stack Overflow question How to determine the variable type in Python?如果您不确定“myline”中的类型,请检查堆栈溢出问题如何确定 Python 中的变量类型? . .

To convert a byte or char to the number it represents, use ord() .要将字节或字符转换为其表示的数字,请使用ord() Here's a simple round trip from an int to bytes and back:这是一个从 int 到 bytes 再返回的简单往返:

>>> number = 3**9
>>> hibyte = chr(number / 256)
>>> lobyte = chr(number % 256)
>>> hibyte, lobyte
('L', '\xe3')
>>> print number == (ord(hibyte) << 8) + ord(lobyte)
True

If your myline variable is string or bytestring, you can use the formula in the last line above.如果您的myline变量是字符串或字节字符串,您可以使用上面最后一行中的公式。 If it somehow is a list of integers, then of course you don't need ord .如果它以某种方式是一个整数列表,那么您当然不需要ord

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM