【问题标题】:C++ : reassembly of a float from 4 bytes [duplicate]C ++:从4个字节重新组装一个浮点数[重复]
【发布时间】:2017-12-03 19:58:37
【问题描述】:

我收到 8 组 4 个字符,代表 8 个浮点数,但我正在努力用 C++ 重新组装它们。

编辑表达思想(这段代码显然是错误的):

// Re-assembly of 32 bytes into 8 float
float concat_value[8];
for (int i = 0; i < 8; i ++) {
concat_value[i] = buffer[4 * i + 3];
concat_value[i] = concat_value[i] << 8;
concat_value[i] = (concat_value[i] & buffer[4 * i + 2]);
concat_value[i] = concat_value[i] << 8;
concat_value[i] = (concat_value[i] & buffer[4 * i + 1]);
concat_value[i] = concat_value[i] << 8;
concat_value[i] = (concat_value[i] & buffer[4 * i + 0]);
std::cout << "   concat_value: " << concat_value[i] << std::endl;
}

很抱歉,我知道它仍然行不通,它只是代表这个想法。

如果你能照亮我。

非常感谢,

让-弗朗索瓦

【问题讨论】:

  • “表示 8 个浮点数”到底是怎么回事?
  • 一个赋值使之前对同一个对象的所有赋值无效,所以整个循环体等价于concat_value[i] = (concat_value[i] &amp; buffer[4 * i + 9 + 0]);
  • 几个问题:buffer的类型是unsigned char[]还是int[]?您将缓冲区直接分配给concat_value,即int[]。 `unsigned char[] 相当于 c++ 中的字节。额外的 + 9 有什么用?您的数据是否以某种方式偏移?您使用的代码不会从缓冲区索引 0-8 中读取任何数据。
  • &amp; 删除数据,不添加数据。
  • 你可能只是 memcpy 从缓冲区到浮动,但这取决于确切的表示和字节序。

标签: c++


【解决方案1】:

在您的文本中,您说缓冲区中有 8 个浮点数的二进制表示。但是你的代码远没有做到这一点。

根据您的代码,缓冲区似乎是浮点数的小端表示,所以我假设您正在 x86 上编译。因此,如果这些假设是正确的,则此代码将起作用:

float concat_value[8];
for (int i = 0; i < 8; i ++) {
    concat_value[i] = *reinterpret_cast<float*>(buffer+i*sizeof(float));
    std::cout << "   concat_value: " << concat_value[i] << std::endl;
}

如果您的目标是只保留 concat_value 浮点数的组成部分,那么:

int concat_value[8];
for (int i = 0; i < 8; i ++) {
    float v = *reinterpret_cast<float*>(buffer+i*sizeof(float));
    std::cout << "   concat_value: " << v << std::endl;
    concat_value[i]=v;
}

【讨论】:

  • 这违反了严格的别名规则。最好改为memcpy
  • 如果buffer 没有正确对齐float 类型的对象,这可能会失败。 memcpy(&amp;concat_value[i], buffer + i*sizeof(float)) 更好,并且尊重 C++ 关于转换指针和通过其他类型的指针访问对象的语义。
  • @interjay,这并不违反严格的别名规则,因为没有两个不同类型的左值指向同一个内存位置。老实说,当我第一次看到它时,我感到很惊讶,他们是 c++20 中一个被接受的名为 bit_cast 的提议,它就是这样做的。
  • @Oliv:关于类型别名:C++ 标准要求程序遵循有关通过适当类型的指针访问对象的规则,以使 C++ 实现能够优化。例如,如果向例程传递int *Afloat *B,则允许编译器推断对A 指向的任何内容的任何更改都不会导致B 指向的任何内容的任何更改,因为它们是不同的类型。优化时,这允许编译器将 B 中的值缓存在寄存器中,而不是从内存中重新加载它们。如果你违反了规则,这个优化就会中断。
  • buffer 的元素类型是char,因此标准规定您不能以float 的身份访问它们,而只能以char 的一些变体形式访问它们。它碰巧持有一个有效的浮点数表示这一事实并没有帮助。你被否决不是因为人们没有阅读这个问题,而是因为你的答案是错误的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-28
  • 2017-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-29
相关资源
最近更新 更多