您的位置:首页 > 其它

C陷阱篇之移位运算

2013-12-15 21:38 190 查看
C语言移位运算有一些不确定性及误区,主要包含两个问题:

右移运算的空出位用0还是符号位填充?换句话右移n位与除以2n是否等价?

无符号整数右移,左边空位会用0填充,所以无符号右移n位与除以2n
等价。

有符号整数右移,用0还是符号位填充由编译器自行决定,C标准中未定义。当有符号数为正数时,符号位也为0,所以总是用0填充,右移n位与除以2n
等价;当有符号数为负,右移后填充位可能为0也可能为1,右移与除以2n不等价。所以要避免对有符号数的右移操作,因为其结果不确定。换句话,无符号数的右移操作才能确保得到期望结果。

课堂上老师总讲,整数右移1位等于除2,移位比除法高效,这其实是很大的误导。能用移位代替除法的场合,编译器会自动优化;而对不能转换的(有符号负数),手动转换,反而落入陷阱,导致错误。去检查一下自己代码里是否包含有符号数的右移操作吧!

保持用移位实现位操作,除法实现算术运算。自己把除法改成移位,纯属画蛇添足。

移位的数量范围怎样确定?

如果待移位的变量长度为n,则移动位数必须大于等于0且小于n。也就是说,一次单独操作中不可能把所有位从变量中移出。例如对于int
n,n << 31和n << 0合法,但n << 32和n << -1则完全非法。这也是包含移位操作的代码要注意的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: