How can I convert two bytes of an integer back to an integer in Python?
I am currently using Arduino
, which outputs some integers (int) through Serial (using pySerial
) a Python script that I am writing Arduino
to communicate with X-Plane
, a flight simulator.
I was able to split the original by two so that I could send it to the script, but I am having little trouble recovering the original integer.
I tried to use the basic bitwise operators (<<, β etc.) as would be done in a C ++-like program, but it doesn't seem to work.
I suspect it has something to do with data types. I can use integers with bytes in the same operations, but I can't tell what type each variable is, since you don't really declare variables in Python as far as I know (I'm very new to Python).
self.pot=self.myline[2]<<8
self.pot|=self.myline[3]
source to share
You can use a module struct
to convert between integers and bytes. In your case, to convert from a Python integer to two bytes and back, you should use:
>>> import struct
>>> struct.pack('>H', 12345)
'09'
>>> struct.unpack('>H', '09')
(12345,)
The first argument struct.pack
and struct.unpack
indicates how you want to format the data. Here I ask it to be in big end mode using a prefix >
(you can use <
for little-endian or =
for native) and then I say there is one unsigned short (16-bit integer) represented H
.
Other bytes b
for signed byte, b
for unsigned byte, H
for signed short (16 bits), i
for signed 32-bit integer, i
for 32-bit unsigned integer. You can get a complete list by looking at the module's documentation struct
.
source to share
It sounds like you think it should work if the data stored in myline
has a high byte:
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 is the least significant byte first, you will need to do the reverse path:
myline = [0, 1, 2, 3]
pot = myline[3]<<8 | myline[2]
print 'pot: {:d}, 0x{:04x}'.format(pot, pot) # outputs "pot: 770, 0x0302"
source to share
This completely works:
long = 500
first = long & 0xff #244
second = long >> 8 #1
result = (second << 8) + first #500
If you are unsure about the types in myline, please check the stack overflow question How do I determine the type of a variable in Python? ...
source to share
To convert a byte or char to the number it represents use ord()
. Here's a simple backtrack from int to bytes and back:
>>> 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 variable myline
is a string or bytestring then you can use the formula on the last line above. If it is somehow a list of integers, then of course you don't need to ord
.
source to share