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.