2014-11-14 3 views
0

Я пытаюсь преобразовать число, хранящееся в виде списка int, в тип float. Я получил номер через последовательную консоль и хочу снова собрать его в поплавок. Как я хотел бы сделать это в C-то вроде этого:Преобразовать список ints в float

bit_data = ((int16_t)byte_array[0] << 8) | byte_array[1]; 
result = (float)bit_data; 

То, что я пытался использовать в Python является гораздо более простое преобразование:

result = int_list[0]*256.0 + int_list[1] 

Однако это не сохраняет знак результата, как это делает код C. Каков правильный способ сделать это в python?

ОБНОВЛЕНИЕ: Версия для Python - 2.7.3. My byte array имеет длину 2. в коде python byte_array - это список ints. Я переименовал его, чтобы избежать недоразумений. Я не могу просто использовать функцию float(), потому что она не сохранит знак числа.

+0

Как велика ваша byte_array? Это 4 элемента? Ваш код не делает это ясным ... –

+0

Кроме того, вы не указали, какую версию python ... –

+1

Что такое byte_array? Является ли список объектов int, байтового объекта? – Dunes

ответ

2

Я немного смущен данными, которые у вас есть, и тем, как они представлены на Python. Насколько я понимаю, вы получили два неподписанных байта по последовательному соединению, которые теперь представлены списком из двух наборов python. Эти данные представляют собой 16-разрядное целое число со знаком большого конца, которое вы хотите извлечь и превратить в float. например.[0xFF, 0xFE] ->-2 ->-2.0

import array, struct 

two_unsigned_bytes = [255, 254] # represented by ints 
byte_array = array.array("B", two_unsigned_bytes) 
# change above to "b" if the ints represent signed bytes ie. in range -128 to 127 
signed_16_bit_int, = struct.unpack(">h", byte_array) 
float_result = float(signed_16_bit_int) 
+1

Я hadn ' t считается преобразованием в массив байтов ... очень круто. Я думаю, что его большой эндиан ... так что "> h". Пример, отличный от '[255, 255]', делает его более понятным. – tdelaney

+0

Спасибо! Это мне больше всего подходит! – Egor

+0

@tdelaney Хороший звонок, о контенте. Меня повесили на знаке данные и пытались задуматься о шаблоне байта, значение которого было иным, но очевидным как для подписанных, так и для unsigned ints. – Dunes

2

Я не уверен, что я действительно понимаю, что вы делаете, но я думаю, что вы получили 4 байта от потока и знаете, что они представляют значение float32. То, как вы справляетесь с этим, предполагает порядок байтов бай-инов.

Python имеет пакет struct (https://docs.python.org/2/library/struct.html) для обработки сквозных потоков.

import struct 

stream = struct.pack(">f", 2/3.) 
len(stream) # 4 

reconstructed_float = struct.unpack(">f", stream) 
+0

Спасибо за быстрый ответ! Я новичок в Python, поэтому мне нужно немного времени, чтобы попробовать и понять. – Egor

2

Я думаю, что вы хотите, это struct module.

Вот круглый фрагмент поездки:

import struct 
sampleValue = 42.13 
somebytes = struct.pack('=f', sampleValue) 
print(somebytes) 
result = struct.unpack('=f', somebytes) 
print(result) 

result может быть удивительным для вас. unpack возвращает кортеж. Таким образом, чтобы добраться до значения вы можете сделать

result[0] 

или изменить линию установки результата быть

result = struct.unpack('=f', some bytes)[0] 

Я лично ненавижу, поэтому использовать следующие вместо

result , = struct.unpack('=f', some bytes) # tuple unpacking on assignment 

во второй вещь, которую вы заметите, заключается в том, что значение имеет дополнительные цифры шума. Это связано с тем, что собственное представление с плавающей запятой python - double.

(Это python3 кстати, настроить для использования старых версий питона в зависимости от обстоятельств)

+0

Спасибо за быстрый ответ! Я новичок в Python, поэтому я буду – Egor

+0

приветствуется на борту. Это веселый/способный язык. –

+0

Вы можете принять этот ответ, если хотите. Стоит отметить, что структурный модуль не знает типы с плавающей запятой с полуточной точностью –

1

Хорошо, так что я думаю, int_list это на самом деле не просто список Интс. Ints ограничены 0-255 и представляют байты, которые могут быть встроены в целое число со знаком. Затем вы хотите превратить это в поплавок. Трюк состоит в том, чтобы правильно установить знак первого байта, а затем обработать так же, как и вы.

float((-(byte_array[0]-127) if byte_array[0]>127 else byte_array[0])*256 + byte_array[1]) 
Смежные вопросы