逻辑移位
汇编指令:shl x y,逻辑左移,把x的每个二进制位向左移动y位,移动造成的最右边的空位由0补足,最左边的数溢出。
shr x y,逻辑右移,把x的每个二进制位向右移动y位,移动造成的最左边的空位由0补足,最右边的数溢出。
算数移位
汇编指令:sal x y,算数左移,与逻辑左移完全相同。
sar x y,算数右移,与逻辑右移大致相同,区别在于移动造成的最左边的空位由符号位(最高位)补足而不是由0补足。
循环移位
汇编指令:rol x y,循环左移,把x的每个二级制位向左移动y位,移动造成的右边的空位由最左边溢出的位补足。
ror x y ,循环右移,与循环左移完全相反,把x的每个二进制位向右移动y位,移动造成的最左边的空位由右边溢出的位补足。
C++中并没有提供循环移位的操作符,但是我们可以通过其他运算的组合来实现它。
对于32位无符号整数x,表达式(x<<y)|(x >> (32-y))可以实现循环左移的功能。
(x>>y)|(x<<(32-y))则可以实现循环右移的功能。
二进制位的修改和查询
读取某些位,先将x右移pos位,是要读取的位移到最低位,再通过&1将其取出。
bool readBit(u32 x , int pos)
{
return (x >> pos) & 1;
}
读x的第pos位开始的cnt位,首先将x右移pos位,再通过&mask来取出最后的cnt位,mask最后cnt个位为1,其余位为0,可以由(1<<cnt)-1得到
u32 readBits(u32 x ,int pos ,int cnt)
{
return (x >> pos) & (( 1u << cnt) - 1);
}
将某些位置为1
u32 setBit(u32 x,int pos)
{
return x | (1u <<pos);
}
将某些位置为0
u32 clearBit(u32 x,int pos)
{
return x & ~(1u<<pos);
}
取反某些位
u32 flipBit(u32 x,int pos)
{
return x^(1u << pos);
}