C语言很多操作都是以字节为单位进行的,但有时为了节约空间,很多系统程序中要求在比特位级别进行运算处理。C语言一同提供了六种位运算的运算符,分别为&(按位与),|(按位或),~(按位取反),^(按位异或),<<(左移),>>(右移)。本次我们就进行移位操作的分析,看看在不同情况下移位操作的情形。
(1)变量为正数的情形
当变量为正数的时候,无论左移还是右移,移动溢出的位丢弃,剩下的位补的都是0。
1.当移位的位数大于,0,并且小于所定义的类型的位数(如变量为整型,那他移位的范围在0~32之间)(左移和右移)
按照正常的情况处理,即将变量的二进制位移动相应的位数,然后在空出来的位上补零即可。
2。当移位的位数大于0,并且超出了所定义类型的位数(左移和右移)
将所移动的位数除以32取得的余数即为移位的位数,按照步骤一执行。
(2)变量为负数的情形
1.右移正数位,且右移位数小于所定义类型的位数 负数的右移与正数的右移规则一样,唯一不同的是正数右移左边补得是0,而负数右移左边补的是1,即符号(传说中的符号移位)。由于是负数,在计算机中以补码存储,即二进制的原码取反加1.然后以移位规则进行移位。即将所求的的补码向右移动相应的位数,左边空出来的位都用1来补齐。然后将这个补码的结果还原成原码即为所求。
2.右移正数位,并且右移的位数大于所定义类型的位数
将所移动的位数除以32所取得的余数即为移位的位数,然后操作上面1.的过程。
3.左移正数位(移动位数小于所定义类型的位数,移动位数大于所定义类型的位数)
负数左移与正数左移一样,左移右边补0.区别是,负数在计算机中以补码存在。一味地过程是对负数求补码,进行移位后,再将补码结果还原成原码即为所求。
(3)移动的位数为负时
1.右移负位数(移动位数的绝对值小于所定义类型的位数)
右移负数位,实则是向相同的方向移动所定义类型的位数与所移动位数的绝对值之差,如果右移-31位,即32-|-31|=1,相当于右移了1位。只要知道如何将其移动的负数位转化为相应移动的整数位后,就可以按照相应的移位步骤进行移位了。
2.右移负数位(移动位数的绝对值大于所定义类型的位数)
一旦右移负数位的绝对值超过所定义类型的位数时,要将其进行取模,把范围控制在所定义的类型位数之内,如果右移-33位,即|-33|%32=1,相当于右移-1位,根据上面的讲解,右移-1位就是右移31位。
3.左移负数位
同上面1,2。
一个小技巧:value(value不能是负数)向右移动n(n小于所定义类型位数)位,其结果等于value/2^n,value向左移动n(n小于所定义类型的位数)位,其结果等于value*2^n.