преобразовать байтовый вектор в вектор с плавающей точкой - PullRequest
1 голос
/ 19 апреля 2019

Я отправляю поток байтов фиксированной длины через последовательный порт на другой компьютер, и я хотел бы попытаться преобразовать поток байтов в вектор чисел с плавающей запятой.

Мой поток имеет разделитель stop, и я использую эту последовательную библиотеку.

Моя текущая реализация включает в себя следующее:

Я прочиталстрока

 std::string data_string;
 ser.readline(data_string, 2052, "stop");

Проверить, заканчивается ли строка разделителем

 if(boost::algorithm::ends_with(stop_string, "stop"))
    {                
       if(data_string.length() == 2052)

Затем преобразовать строку в вектор

   std::vector<unsigned char>bytes(stop_string.begin(), stop_string.end());

Затем я использую цикл forи memcpy для преобразования bytes в массив чисел с плавающей запятой.

     unsigned char temp_buffer[4];
     float float_values[513] = { 0 };
     int j = 0;
     for(size_t i = 4; i < 2052; i+=4)
          {
              temp_buffer[0] = bytes[i - 4];
              temp_buffer[1] = bytes[i - 3];
              temp_buffer[2] = bytes[i - 2];
              temp_buffer[3] = bytes[i - 1];
              memcpy(&float_values[j], temp_buffer, sizeof(float));
              j++;
           }

Но этот метод выглядит громоздким, и я бы хотел избежать цикла for.Есть ли способ:

  • преобразовать вектор bytes в вектор чисел с плавающей запятой вместо этого?

  • избежать цикла for?

Ответы [ 2 ]

1 голос
/ 19 апреля 2019

Массив с плавающей точкой и вектор беззнаковых символов имеют одинаковый размер в байтах.Вы можете просто записать memcpy прямо в массив float из вашего буфера.

Это не так, как если бы ваши байты менялись местами или что-то в этом роде.Вы просто хотите интерпретировать 4 последовательных байта как число с плавающей запятой.

Это также устраняет цикл ?

EDIT UPDATE:

Если вы используете C ++ 11 или выше, вы можете положиться на тот факт, что внутренний буфер std :: string хранится непрерывно и просто копировать непосредственно из него.Нет необходимости во временном буфере байтов, который экономит значительный объем памяти (полстраницы).

Пример:

// copy directly from string
float float_values[data_string.size()/sizeof(float)]; // 513
std::memcpy(float_values, data_string.data(), data_string.size());
1 голос
/ 19 апреля 2019

Поскольку вы пометили как общий C ++, я буду использовать некоторые интересные новые функции, представленные C ++ 20:)

#include <algorithm>
#include <cstddef>
#include <span>
#include <vector>

std::vector<float> ToFloats(const std::vector<std::byte>& bytes) {
    std::vector<float> floats(bytes.size() / sizeof(float), 0.0f);
    std::copy_n(bytes.begin(), floats.size() * sizeof(float),
                std::as_writable_bytes(std::span(floats)).begin());
    return floats;
}

Пример в реальном времени (std::byte, std::span, std:: as_writable_bytes)

...