简体   繁体   中英

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? 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.

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

 #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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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