Swap bits in c++ for a double

时光总嘲笑我的痴心妄想 提交于 2019-12-05 17:37:40

I'd probably try something like this:

template <typename T>
void swap_endian(T& pX)
{
    // should static assert that T is a POD

    char& raw = reinterpret_cast<char&>(pX);
    std::reverse(&raw, &raw + sizeof(T));
}

Short and sweet (and relatively untested). The compiler will make all the necessary optimizations. The above is well-defined for any POD type, and doesn't rely on any implementation details.

A copy version, for when you don't want to modify the argument:

template <typename T>
T swap_endian_copy(T pX)
{
    swap_endian(pX);
    return pX;
}

There are some important pitfalls to pay attention to when dealing with the binary representation of floats or doubles.

Can't you just swap them around?

inline unsigned long long EndianChange( double d )
{
    char ch[8];
    memcpy( ch, &d, 8 );  // Note this will be optimised out completely by pretty much every compiler.
    ch[0] ^= ch[7] ^= ch[0] ^= ch[7]; 
    ch[1] ^= ch[6] ^= ch[1] ^= ch[6];
    ch[2] ^= ch[5] ^= ch[2] ^= ch[5];
    ch[3] ^= ch[4] ^= ch[3] ^= ch[4];

    unsigned long long dRet;
    memcpy( &dRet, ch, 8 ); // Again this will get optimised out.
    return dRet;
};

Edit: As pointed out the byte swapped double "can" get loaded into a register so that getting it back out of that register can mean the value is no longer valid so store it in a long long, 64-bit to avoid this problem.

Thats all there is to a byte swap. I'm not sure what you are trying to do but every big endian platform I've ever used uses the same encoding as little-endian just the byte order reversed. The above code will reverse the byte order for you. Pretty much any compiler will simply do the byte swap and then return the byte swapped variable and get rid of the memcpys. This is a good way to deal with aliasing issues.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!