2015-12-03 5 views
0

Мне нужна помощь. Я новичок в python. Я пытаюсь выполнить следующее, которое написано на C++ в python. Вот что у меня есть:Перевод манипулятора Манипуляции в C++ на Python

C++:

uint16_t value = (ReadData[1] << 8 | ReadData[2]); 
int num = (short) value; 
int total = ((0.89*num)+48.31); 

Python:

ReadData = [0]*6 
arr = bytes(ReadData) 
value = arr2[0:3] 

Не знаете, как взять массив, который выплюнуть, как так: b'\xff\xff\xce' к подписанному междунар.

Заранее спасибо.

+0

Можете ли вы описать, что вы хотите достичь, семантически? – MaxNoe

ответ

2

Поскольку вы используете bytes и bytes литералов Я предполагаю, что вы на Python 3, в в этом случае у вас есть намного лучший общий вариант для преобразования произвольных прогонов байтов в int. Python 3 имеет потрясающий все в одном конвертере. Для вашего примера:

>>> int.from_bytes(b'\xff\xff\xce', 'big', signed=True) 
-50 

Он весит до огромных размеров и работает быстрее, чем все остальное.

Если вы не используете Python 3, это немного уродливее, но все же довольно быстро:

import binascii 

def int_from_bytes(b): 
    x = int(binascii.hexlify(b), 16) 
    mask = 1 << (len(b) << 3) - 1 
    if x & mask: 
     x -= mask << 1 
    return x 

который получает те же результаты, как Python 3 встроенных, когда вы делаете:

>>> int_from_bytes(b'\xff\xff\xce') 
-50 

Замечание об исполнении: Предварительно скомпилированный struct.Struct победит, раздастся, если это действительно так просто, как один байт-байт, за которым следует подписанный short, бессмысленной длины переменной длины.В этом случае, вы бы прекомпиляцию Struct с:

unpacker = struct.Struct('>xh').unpack 

Затем вы можете использовать его так:

x, = unpacker(b'\xff\xff\xce') 

волочить запятой важно (Struct.unpack возвращает Len 1 кортеж в этом случае, и присваивание x, распаковывает единственное значение в x.

+0

Если вы действительно хотели обработать два байта, и у вас было значение в ReadData, вы хотели пропустить один байт и взять следующие два из них, вы должны сделать 'int.from_bytes (ReadData [1: 3 ], 'big', signed = True) '(секция' [1: 3] 'вырезает нужные вам байты) или с помощью hack-совместимости' int_from_bytes (ReadData [1: 3]) '. – ShadowRanger

0

Python поддерживает побитовые операции, которые очень похожи на C++. Если у вас есть массив Python int называеться ReadData, вы можете сделать следующее:

value = (ReadData[1] & 0xFF) << 8 | (ReadData[2] & 0xFF) 
total = ((0.89 * value) + 48.31) 

& 0xFF удаляет все, кроме младшего байта числа, который, кажется, что вы хотите.

0

Использовать модуль struct для интерпретации bytes string как C данных.

Если вы хотите, чтобы интерпретировать байты 1 и 2 ReadData в большой обратный порядок байт подписал 16-битную integar, сделайте следующее:

import struct 

ReadData = b'\xff\xff\xce' 

# ReadData[1:] takes from ReadData[1] until ReadData[-1] (the last one) 
num = struct.unpack('>h', ReadData[1:]) 
# Now num is -50 

Что было бы эквивалентно:

# Convert ReadData to unsigned int 
num = (ReadData[1] & 0xFF) << 8 | (ReadData[2] & 0xFF) 

# Change sign, assuming we got 16-bit number 
num = num - 0x10000 

Преобразование num до total должно быть тривиально:

total = ((0.89*num)+48.31) 

Однако обратите внимание, что 0.89 * num будет брось плавать, так что, возможно, захотите сделать вместо этого,

total = int((0.89 * num) + 48.31) 
+0

Согласитесь с этим, если это действительно только два байта, которые вам нужны о (хотя вручную принудительное отрицание, не проверяя высокий бит, является плохой формой в коде сдвига и маски). Если им нужно обработать три (а срез в Python вытащил все три), то 'struct' не может много помочь, так как он работает с мощностью 2-х размеров. – ShadowRanger

+0

@ShadowRanger, спасибо, без большого знания приложений трудно предоставить более общий/безопасный ответ. И предположение, что 'ReadData' равно 3 байтам, звучит так же произвольно, как я думаю, что пара (1,2) является вашим целым числом. – memoselyk

Смежные вопросы