前提:32位CPU,int型4字节,long型8字节;
1 结论
(1)short、char类型的数据在做移位运算之前,会被自动转换为int类型,然后再进行运算;本质原因:运算过程中CPU会将char型的数据放到寄存器中,因为CPU是32为的所以数据在寄存器中移位的范围也是32位,运算后赋值给左值时会根据左值的字长进行数据的截取;
(2)long经过移位运算后结果为long类型;
(3)特别注意,如果移位前的有效数据位,移位后所在位置超过int型数据的位数上限,则此部分数据会被截断;
2实战
2.1 32位以下移位
综上所述,char、short、int型数据移位时,需要注意移位后有效数据位是否超过32,是的话则会被截断,只保留32bit,实战应用例如:
#define SWAP32(x) ((((x) & 0x000000FF) << 24) | (((x) & 0x0000FF00) << 8) | \
(((x) & 0x00FF0000) >> 8) | (((x) & 0xFF000000) >> 24))
2.2 32位以上移位
Usigned long long(uint64)类型数据做移位操作,需要在移位前,移位后都要做数据类型强转,将数据强转成uint64类型(否则系统会默认截断到32bit),实战应用例如:
#define SWAP64(x) ((uint64_t)((((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) | \
(((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
(((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
(((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \
(((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \
(((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
(((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
(((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56) ))