Chinaunix首页 | 论坛 | 博客
  • 博客访问: 316802
  • 博文数量: 57
  • 博客积分: 146
  • 博客等级: 入伍新兵
  • 技术积分: 769
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-29 14:57
文章分类
文章存档

2014年(39)

2013年(13)

2012年(5)

我的朋友

分类: C/C++

2014-06-30 15:10:23

移位操作分为左移位<<和右移位>>两种,C规定若移位的右操作数为负数或大于等于左操作数的位宽(int为32位,char为8位)时,其行为未定义。

1.符号类型的左移位
左移位操作,空位部分填充零。如下图:

错误代码:

点击(此处)折叠或打开

  1. int si1, si2, sresult;
  2. sresult = si1 << si2
若si2为负数或大于等于sizeof(int)*CHAR_BIT时,行为未定义。

正确:

点击(此处)折叠或打开

  1. int si1, si2, sresult;
  2. if ( (si1 < 0) || (si2 < 0) || (si2 >= sizeof(int)*CHAR_BIT) || si1 > (INT_MAX >> si2) ) {
  3. /* handle error condition */
  4. }
  5. else {
  6. sresult = si1 << si2;
  7. }

2.无符号类型的左移位:空位部分填充零。
错误:

点击(此处)折叠或打开

  1. unsigned int ui1, ui2, uresult;
  2. uresult = ui1 << ui2
当ui2大于等于sizeof(int)*CHAR_BIT,行为未定义。
正确:

点击(此处)折叠或打开

  1. unsigned int ui1, ui2, uresult;
  2. if ( (ui2 >= sizeof(unsigned int)*CHAR_BIT) || (ui1 > (UINT_MAX >> ui2))) ) {
  3. /* handle error condition */
  4. }
  5. else {
  6. uresult = ui1 << ui2;
  7. }
3.右移位操作
列如,E1>>E2,若E1为有符号类型且为负值,则其行为是implementation-defined,其实现由编译器决定,可以是算术右移位或逻辑右移位。


算术右移操作:移出的空白位用符号位填充。下图符号位为1,空白就用1填充。



逻辑右移位:就是空白位用0填充。




错误代码:

点击(此处)折叠或打开

  1. int si1, si2, sresult;
  2. unsigned int ui1, ui2, uresult;
  3. sresult = si1 >> si2;
  4. uresult = ui1 >> ui2
对si2或ui2没有做判断。
正确:

点击(此处)折叠或打开

  1. int si1, si2, sresult;
  2. unsigned int ui1, ui2, result;
  3. if ( (si2 < 0) || (si2 >= sizeof(int)*CHAR_BIT) ) {
  4. /* handle error condition */
  5. }
  6. else {
  7. sresult = si1 >> si2;
  8. }
  9. if (ui2 >= sizeof(unsigned int)*CHAR_BIT) {
  10. /* handle error condition */
  11. }
  12. else {
  13. uresult = ui1 >> ui2;
  14. }












阅读(1124) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~