c++ - memcpy是将float打包到uint32中的标准方法吗?

标签 c++ process type-conversion memcpy

以下是将浮点数打包到uint32中的最佳方法吗?这可能是一种快速简便的方法,但是我想确保没有更好的方法,或者确保在流程之间交换值(value)不会带来奇怪的皱纹。

就我而言,“最佳”是,它永远不会在兼容的C++编译器上中断(考虑到静态断言),可以在同一台计算机上的两个进程之间进行打包和拆包,并且与将uint32复制到另一个计算机中一样快uint32。

流程A:

static_assert(sizeof(float) == sizeof(uint32) && alignof(float) == alignof(uint32), "no");
...

float f = 0.5f;
uint32 buffer[128];

memcpy(buffer + 41, &f, sizeof(uint32)); // packing

流程B:
uint32 * buffer = thisUint32Is_ReadFromProcessA(); // reads "buffer" from process A
...

memcpy(&f, buffer + 41, sizeof(uint32)); // unpacking

assert(f == 0.5f);

最佳答案

是的,这是进行类型校正的标准方法。 Cppreferences在 memcpy 上的页面甚至包括一个示例,该示例显示了如何使用它来将double重新解释为int64_t

#include <iostream>
#include <cstdint>
#include <cstring>

int main()
{
    // simple usage
    char source[] = "once upon a midnight dreary...", dest[4];
    std::memcpy(dest, source, sizeof dest);
    for (char c : dest)
        std::cout << c << '\n';  
    // reinterpreting
    double d = 0.1;
//  std::int64_t n = *reinterpret_cast<std::int64_t*>(&d); // aliasing violation
    std::int64_t n;
    std::memcpy(&n, &d, sizeof d); // OK     
    std::cout << std::hexfloat << d << " is " << std::hex << n
              << " as an std::int64_t\n";
}

ouput

o
n
c
e
0x1.999999999999ap-4 is 3fb999999999999a as an std::int64_t


只要断言通过(您正在写入和读取正确数量的字节),该操作便是安全的。您不能将64位对象打包到32位对象中,但是可以将一个32位对象打包到另一个32位对象中,只要它们是trivially copyable

关于c++ - memcpy是将float打包到uint32中的标准方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59198511/

相关文章:

c# - 启动进程时以编程方式设置启动位置

c++ - C++ 标准是否指定在某些情况下编译应该失败并出现错误?

c++ - 从类到 double 的隐式转换

c++ - 将整数数组转换为空指针 - pthread_create

c++ - 使用TFS生成版本头文件

c - 找出进程数

c++ - 较大类中的两个类共享数据

c - pipe() 从 1 个父进程到单独的 c 文件中的多个子进程

c++ - 类模板参数推导失败导致替换失败

c# - 如何使用泛型在 C# 中将类型静态绑定(bind)在一起(如 TypeToType<T>)?