从字节缓冲区获取浮点值?
Get float values back from byte buffer?
我目前正在学习 C++,目前我正在试验指针和结构。在下面的代码中,我将向量 A 复制到大小为 100 字节的缓冲区中。之后,我将向量 B 复制到具有偏移量的同一缓冲区中,以便向量在缓冲区中彼此相邻。之后,我想再次在缓冲区中找到向量并计算向量之间的点积。
#include <iostream>
const short SIZE = 5;
typedef struct vector {
float vals[SIZE];
} vector;
void vector_copy (vector* v, vector* target) {
for (int i=0; i<SIZE; i++) {
target->vals[i] = v->vals[i];
}
}
float buffered_vector_product (char buffer[]) {
float scalar_product = 0;
int offset = SIZE * 4;
for (int i=0; i<SIZE; i=i+4) {
scalar_product += buffer[i] * buffer[i+offset];
}
return scalar_product;
}
int main() {
char buffer[100] = {};
vector A = {{1, 1.5, 2, 2.5, 3}};
vector B = {{0.5, -1, 1.5, -2, 2.5}};
vector_copy(&A, (vector*) buffer);
vector_copy(&B, (vector*) (buffer + sizeof(vector)));
float prod = buffered_vector_product(buffer);
std::cout << prod <<std::endl;
return 0;
}
很遗憾,这还行不通。问题出在函数 buffered_vector_product
中。我无法从缓冲区中取回浮点值。每个浮点值应该需要 4 个字节。我不知道如何访问这 4 个字节并将它们转换为浮点值。谁能帮我吗?非常感谢!
在函数 buffered_vector_product
中,更改行
int offset = SIZE * 4;
for (int i=0; i<SIZE; i=i+4) {
scalar_product += buffer[i] * buffer[i+offset];
}
到
for ( int i=0; i<SIZE; i++ ) {
scalar_product += ((float*)buffer)[i] * ((float*)buffer)[i+SIZE];
}
如果您想手动计算偏移量,可以将其替换为以下内容:
size_t offset = SIZE * sizeof(float);
for ( int i=0; i<SIZE; i++ ) {
scalar_product += *(float*)(buffer+i*sizeof(float)) * *(float*)(buffer+i*sizeof(float)+offset);
}
然而,对于这两种解决方案,您都应该注意对齐限制和 strict aliasing rule。
对齐限制的问题可以通过更改行来解决
char buffer[100] = {};
以下内容:
alignas(float) char buffer[100] = {};
严格的别名规则是一个复杂得多的问题,因为确切的规则在不同的 C++ 标准之间发生了显着变化,并且(或至少曾经)不同于 C 语言中的严格别名规则。有关此问题的更多信息,请参阅评论部分中的 link。
我目前正在学习 C++,目前我正在试验指针和结构。在下面的代码中,我将向量 A 复制到大小为 100 字节的缓冲区中。之后,我将向量 B 复制到具有偏移量的同一缓冲区中,以便向量在缓冲区中彼此相邻。之后,我想再次在缓冲区中找到向量并计算向量之间的点积。
#include <iostream>
const short SIZE = 5;
typedef struct vector {
float vals[SIZE];
} vector;
void vector_copy (vector* v, vector* target) {
for (int i=0; i<SIZE; i++) {
target->vals[i] = v->vals[i];
}
}
float buffered_vector_product (char buffer[]) {
float scalar_product = 0;
int offset = SIZE * 4;
for (int i=0; i<SIZE; i=i+4) {
scalar_product += buffer[i] * buffer[i+offset];
}
return scalar_product;
}
int main() {
char buffer[100] = {};
vector A = {{1, 1.5, 2, 2.5, 3}};
vector B = {{0.5, -1, 1.5, -2, 2.5}};
vector_copy(&A, (vector*) buffer);
vector_copy(&B, (vector*) (buffer + sizeof(vector)));
float prod = buffered_vector_product(buffer);
std::cout << prod <<std::endl;
return 0;
}
很遗憾,这还行不通。问题出在函数 buffered_vector_product
中。我无法从缓冲区中取回浮点值。每个浮点值应该需要 4 个字节。我不知道如何访问这 4 个字节并将它们转换为浮点值。谁能帮我吗?非常感谢!
在函数 buffered_vector_product
中,更改行
int offset = SIZE * 4;
for (int i=0; i<SIZE; i=i+4) {
scalar_product += buffer[i] * buffer[i+offset];
}
到
for ( int i=0; i<SIZE; i++ ) {
scalar_product += ((float*)buffer)[i] * ((float*)buffer)[i+SIZE];
}
如果您想手动计算偏移量,可以将其替换为以下内容:
size_t offset = SIZE * sizeof(float);
for ( int i=0; i<SIZE; i++ ) {
scalar_product += *(float*)(buffer+i*sizeof(float)) * *(float*)(buffer+i*sizeof(float)+offset);
}
然而,对于这两种解决方案,您都应该注意对齐限制和 strict aliasing rule。
对齐限制的问题可以通过更改行来解决
char buffer[100] = {};
以下内容:
alignas(float) char buffer[100] = {};
严格的别名规则是一个复杂得多的问题,因为确切的规则在不同的 C++ 标准之间发生了显着变化,并且(或至少曾经)不同于 C 语言中的严格别名规则。有关此问题的更多信息,请参阅评论部分中的 link。