将字节向量转换为浮点向量
convert a byte vector into a vector of floats
我正在通过串行端口向另一台计算机发送固定长度的字节流,我想尝试将字节流转换为浮点数向量。
我的流有一个分隔符 stop
,我正在使用 this 串行库。
我目前的实施涉及以下内容:
我读了一个字符串
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 循环?
既然你标记为通用 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;
}
Live Example
(std::byte
, std::span
, std:: as_writable_bytes
)
浮点数数组和无符号字符向量的字节大小相同。您可以直接从缓冲区中 memcpy 到浮点数数组中。
这并不是说你的字节被交换了或什么的。您只想将 4 个连续字节解释为浮点数。
这也消除了循环
编辑更新:
如果您使用的是 C++11 或更高版本,您可以依赖 并直接从中复制。不需要临时字节缓冲区,这会为您节省大量内存(半页)。
示例:
// copy directly from string
float float_values[data_string.size()/sizeof(float)]; // 513
std::memcpy(float_values, data_string.data(), data_string.size());
我正在通过串行端口向另一台计算机发送固定长度的字节流,我想尝试将字节流转换为浮点数向量。
我的流有一个分隔符 stop
,我正在使用 this 串行库。
我目前的实施涉及以下内容:
我读了一个字符串
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 循环?
既然你标记为通用 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;
}
Live Example
(std::byte
, std::span
, std:: as_writable_bytes
)
浮点数数组和无符号字符向量的字节大小相同。您可以直接从缓冲区中 memcpy 到浮点数数组中。
这并不是说你的字节被交换了或什么的。您只想将 4 个连续字节解释为浮点数。
这也消除了循环
编辑更新:
如果您使用的是 C++11 或更高版本,您可以依赖
示例:
// copy directly from string
float float_values[data_string.size()/sizeof(float)]; // 513
std::memcpy(float_values, data_string.data(), data_string.size());