二元移位算子。如何确定操作后的值?

时间:2013-01-23 04:22:13

标签: c

是否有简单的方法来确定有符号数字的左移或右移输出? This页面将左移位置描述为expr1*2*expr2,将右侧位置描述为expr1/2*expr2,但是当我在CI中尝试类似27 << 5的内容时,获得的值大于27*2*5 = 270 }。另外,对于负输入,例如-27 << 4-120 >> 5,这些操作如何工作?在轮班工作时是否需要考虑特殊情况?

2 个答案:

答案 0 :(得分:3)

移位相当于乘以 2的幂,而不仅仅是参数乘积的两倍。换句话说,27 <&lt;&lt; 5 == 27 * 2 5 。右移相当于浮动除法,但没有为负操作数定义。

如果乘以或除以2的固定幂,则最好用*/运算符写出来。如果可能,编译器会将其转换为更快的移位操作,并避免在负数,操作顺序等周围出现粗糙边缘。

有大量资源可以帮助您深入挖掘(或者确实应该在MSDN之前就非平台特定问题进行咨询),例如Wikipedia

答案 1 :(得分:1)

当您向左移动(向左)多个二进制位置时,它不是移位的乘法。它是2^shift的乘法(2到移位的力量)。

例如

shift    multiplier
 1       2
 2       4
 3       8
 4       16

右移是相同的,但实际上是一个分裂。

所以.. 27 << 5就是这样:

27      == 00000000 00011011
27 << 5 == 00000011 01100000 == 864

向右转:

27 >> 1 == 00000000 00001101 == 13
27 >> 2 == 00000000 00000110 == 6
27 >> 3 == 00000000 00000011 == 3
27 >> 4 == 00000000 00000001 == 1
27 >> 5 == 00000000 00000000 == 0

当您移动负数时,我相信最左边的位通常会被保留。我不确定。老实说,我只是转移了无符号数字,我个人不相信转移签名值。

无论何时移位,都需要注意截断(某些位将丢失)。通常它只是被截断的零位,但如果你移动得足够多(或者你向右移动),你将失去1位。这取决于整数类型的容量,绝对可以利用它。