C标准并没有明确定义应该使用哪种类型的右移。对于无符号数据(unsigned Type),右移必须是逻辑的;对于有符号数据,C标准并没有规定使用哪种方式的右移,而实际上,几乎所有的编译器/机器组合都对有符号数据进行算术右移….

 对于一个位表示为[Xn-1,Xn-2,……,X0]的运算数x:
左移:表达式x<<k会生成一个值,其位表示为[Xn-k-1,Xn-k-2,……,X0,0,……,0],也就是说,x向左移动k位,丢弃k个最高位,并在右端补k个0。
逻辑右移(x>>k):在左端补k个0,得到[0,……,0,Xn-1,Xn-2,……,Xk]。
算术右移(x>>k):在左端补k个最高有效位的拷贝,得到[Xn-1,……,Xn-1,Xn-1,Xn-2,……,Xk]。

    C标准并没有明确定义应该使用哪种类型的右移。对于无符号数据(unsigned Type),右移必须是逻辑的;对于有符号数据,C标准并没有规定使用哪种方式的右移,而实际上,几乎所有的编译器/机器组合都对有符号数据进行算术右移。

     下面是测试代码:

void ShiftLeft()
{
      
int i1=~0;
      printf(
左移16位:%x–>%x ,i1,i1<<16);
       unsigned 
int i2=~0;
      printf(
左移16位:%x–>%x ,i2,i2<<16);
}


void LogicRightShift()
{
      unsigned 
int i=~0;
      printf(
逻辑右移16位:%x–>%x ,i,(i>>16));//这里如果左移32位或更多位时, 可能不会得到预期的结果
}


void ArithmeticRightShift()
{
      
int i=~0;
      printf(
算术右移16位:%x–>%x ,i,(i>>16));}


void TestShift()
{
      ShiftLeft();
      LogicRightShift();
      ArithmeticRightShift();
}

 

输出结果:

左移16位:ffffffff–>ffff0000
左移16位:ffffffff–>ffff0000
逻辑右移16位:ffffffff–>ffff
算术右移16位:ffffffff–>ffffffff
Press any key to continue . . .

版权声明:本文为happyhippy原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/happyhippy/archive/2006/12/20/601221.html