//循环左移
#define ROTATE_LEFT(x, n) ((x) << (n)) | ((x) >> ((8*sizeof(x)) - (n)))
//循环右移
#define ROTATE_RIGHT(x, n) ((x) >> (n)) | ((x) << ((8*sizeof(x)) - (n)))
//使用例子:
#include <stdio.h>
int main()
{
unsigned char z=0x81,r=0,m_MoveBits=1
r=ROTATE_LEFT(z,m_MoveBits) //循环左移 1位
printf("0x%02X 循环左移后 = 0x%02X\n",z,r)
z=ROTATE_RIGHT(r,m_MoveBits) //循环右移 1 位
printf("0x%02X 循环右移后 = 0x%02X\n\n",r,z)
z=1 r=0 //初始化 z = 1
m_MoveBits=4 //移4位
r=ROTATE_LEFT(z,m_MoveBits) //循环左移 1位
printf("0x%02X 循环左移后 = 0x%02X\n",z,r)
z=ROTATE_RIGHT(r,m_MoveBits) //循环右移 1 位
printf("0x%02X 循环右移后 = 0x%02X\n",r,z)
return 0
}
左移时是不区分无符号数的,而进行右移时也不区分是否是无符号,移进的值在最高位补0。例如:0xff进行右移一位0xff>>1,其结果为0x7f,请参见以下代码:
#include <stdio.h>
int main()
{
int a = 0xff
a = a >>1
printf("a = %x\n", a)
return 0
}
运行结果为:a = 7f
假设0010
左移就是把二进制数向左移动,右边补0,0的二进制全是0,左移之后右边再补0。
0010<<2 就是1000 实际是做的*4。
1000>>2 计算 0010 实际做的是/4。
位移位运算符是将数据看成二进制数,对其进行向左或向右移动若干位的运算。位移位运算符分为左移和右移两种,均为双目运算符。第一运算对象是移位对象,第二个运算对象是所移的二进制位数。
位移位运算符的运算对象、运算规则与结果、结合性如表2-16所示。
移位时,移出的位数全部丢弃,移出的空位补入的数与左移还是右移花接木有关。如果是左移,则规定补入的数全部是0;如果是右移,还与被移位的数据是否带符号有关。若是不带符号数,则补入的数全部为0;若是带符号数,则补入的数全部等于原数的最左端位上的原数(即原符号位)。具体移位规则如下所示。
位移位运算符的优先级如下:
·算术运算符 优先于 位移位运算符 优先于 关系运算符
·位移位运算符是同级别的,结合性是自左向右
例如,设无符号短整型变量a为0111(对应二进制数为0000000001001001),
则:a<<3 结果为01110(对应二进制数为0000001001001000),a不变
a>>4 结果为04 (对应二进制数为0000000000000100),a不变
又如,设短整型变量a为-4(对应二进制数为1111111111111100),
则:a<<3 结果为-32(对应二进制数为1111111111100000),a不变
a>>4 结果为-1(对应二进制数为1111111111111111),a不变