#include <endian.h>
class Endness
{
public:
template<typename T16>
static inline T16 swap16(const T16& v, BOOL desEndness)
{
if (!(__BYTE_ORDER == __LITTLE_ENDIAN ^ desEndness))
{
return v;
}
return ( (v & 0xff) << 8 ) | (v >> 8 & 0x00ff);
}
template<typename T32>
static inline T32 swap32(const T32& v, BOOL desEndness)
{
if (!(__BYTE_ORDER == __LITTLE_ENDIAN ^ desEndness))
{
return v;
}
return (v >> 24 & 0x000000ff)
| ((v & 0x00ff0000) >> 8 & 0x00ffffff)
| ((v & 0x0000ff00) << 8)
| (v << 24);
}
template <typename T64>
static inline T64 swap64(const T64 &v, BOOL desEndness)
{
if (!(__BYTE_ORDER == __LITTLE_ENDIAN ^ desEndness))
{
return v;
}
return (v >> 56 & 0x00000000000000ff)
| ((v & 0x00ff000000000000) >> 40 & 0x0000000000ffffff)
| ((v & 0x0000ff0000000000) >> 24 & 0x000000ffffffffff)
| ((v & 0x000000ff00000000) >> 8 & 0x00ffffffffffffff)
| ((v & 0x00000000ff000000) << 8)
| ((v & 0x0000000000ff0000) << 24)
| ((v & 0x000000000000ff00) << 40)
| (v << 56);
}
};
注:在C++中位移分为逻辑位移和算术位移。
逻辑位移:不管左移还是右移,对于空缺位补的都是0。即无符号有左右移和有符号的左移。
算术位移:左移,空缺位补的是0。而右移,空缺位补的是符号位(1或0)。即负数右移补1,正数右移补0。
所以在负数位移运算中要特别小心,以上代码中每次右移做一次与运算(如(v >> 8 & 0x00ff)),就是为了解决负数右移补1的问题。