简体   繁体   English

memcpy 是将浮点数装入 uint32 的标准方法吗?

[英]Is memcpy the standard way to pack float into uint32?

Is the following the best way to pack a float's bits into a uint32?以下是将浮点数装入 uint32 的最佳方法吗? This might be a fast and easy yes, but I want to make sure there's no better way, or that exchanging the value between processes doesn't introduce a weird wrinkle.这可能是一个快速而简单的是,但我想确保没有更好的方法,或者在进程之间交换值不会引入奇怪的皱纹。

"Best" in my case, is that it won't ever break on a compliant C++ compiler (given the static assert), can be packed and unpacked between two processes on the same computer, and is as fast as copying a uint32 into another uint32.在我的情况下,“最好”是它永远不会在兼容的 C++ 编译器上中断(给定静态断言),可以在同一台计算机上的两个进程之间打包和解包,并且与将 uint32 复制到另一个进程一样快uint32。

Process 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

Process B:工艺乙:

uint32 * buffer = thisUint32Is_ReadFromProcessA(); // reads "buffer" from process A
...

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

assert(f == 0.5f);

Yes, this is the standard way to do type punning.是的,这是进行类型双关的标准方法。 Cppreferences's page on memcpy even includes an example showing how you can use it to reinterpret a double as an int64_t 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

As long as the asserts pass (your are writing and reading the correct number of bytes) then the operation is safe.只要断言通过(您正在写入和读取正确的字节数),那么操作就是安全的。 You can't pack a 64 bit object in a 32 bit object, but you can pack one 32 bit object into another 32 bit object, as long they are trivially copyable您不能将 64 位对象打包到 32 位对象中,但是您可以将一个 32 位对象打包到另一个 32 位对象中,只要它们是可 简单复制的

Or this:或这个:

union TheUnion {
    uint32 theInt;
    float theFloat;
};

TheUnion converter;

converter.theFloat = myFloatValue;
uint32 myIntRep = converter.theInt;

I don't know if this is better, but it's a different way to look at it.我不知道这是否更好,但这是一种不同的看待它的方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM