设为首页 加入收藏

TOP

15.1.2 移位运算
2013-10-12 06:52:50 来源: 作者: 【 】 浏览:91
Tags:15.1.2移位 运算

15.1.2  移位运算

移位运算符(Bitwise Shift)包括左移<<和右移>>。左移将一个整数的各二进制位全部左移若干位,例如0xcfffffff3<<2得到0x3fffffcc,如图15.2所示。

  

最高两位的11被移出去了,最低两位又补了两个0,其他位依次左移两位。但要注意,移动的位数必须小于左操作数的总位数,比如上面的例子,左边是unsigned int型,如果左移的位数大于等于32位,则结果是Undefined。移位运算符不同于+ - * / ==等运算符,两边操作数的类型不要求一致,但两边操作数都要做Integer Promotion,整个表达式的类型和左操作数提升后的类型相同。

复习一下第13.2节讲过的知识可以得出结论:在一定的取值范围内,将一个整数左移1位相当于乘以2。比如二进制11(十进制3)左移一位变成110,就是十进制的6,再左移一位变成1100,就是十进制的12。读者可以自己验证这条规律对有符号数和无符号数都成立,对负数也成立。当然,如果左移改变了最高位(符号位),那么结果肯定不是乘以2了,所以我加了个前提:"在一定的取值范围内"。由于计算机做移位比做乘法快得多,编译器可以利用这一点进行优化,比如看到源代码中有i * 8,可以编译成移位指令而不是乘法指令。

当操作数是无符号数时,右移运算的规则和左移类似,例如0xcfffffff3>>2得到0x33fffffc,如图15.3所示。

   

最低两位的11被移出去了,最高两位又补了两个0,其他位依次右移两位。和左移类似,移动的位数也必须小于左操作数的总位数,否则结果是Undefined。在一定的取值范围内,将一个整数右移1位相当于除以2,小数部分截掉。

当操作数是有符号数时,右移运算的规则比较复杂:

如果是正数,那么高位移入0

如果是负数,那么高位移入1还是0不一定,这是Implementation-defined的。对于x86平台的gcc编译器,最高位移入1,也就是仍保持负数的符号位,这种处理方式对负数仍然保持了"右移1位相当于除以2"的性质。

综上所述,由于类型转换和移位等问题,用有符号数做位运算是很不方便的,所以,建议只对无符号数做位运算,以减少出错的可能性。

习题

1.下面两行printf语句打印的结果有何不同?请读者比较分析一下。%x转换说明的含义详见第25.2.9节。

  1. int i = 0xcffffff3;  
  2. printf("%x\n", 0xcffffff3>>2);  
  3. printf("%x\n", i>>2); 


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇15.4 运算符总结 下一篇15.1.3 掩码

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: