c解释中的按位运算

时间:2014-02-03 22:50:15

标签: c bit-manipulation

我在c中有以下代码:

 unsigned int a = 60; /* 60 = 0011 1100 */
 int c = 0;
 c = ~a; /*-61 = 1100 0011 */
 printf("c = ~a = %d\n", c );
 c = a << 2; /* 240 = 1111 0000 */
 printf("c = a << 2 = %d\n", c );

第一个输出是-61而第二个输出是240.为什么第一个printf计算1100 0011的二进制补码而第二个只是将1111 0000转换为十进制等值?

2 个答案:

答案 0 :(得分:6)

您假设int只有8位宽。您的系统可能不是这种情况,int可能使用16位或32位。

在第一个例子中,所有位都被反转。这实际上是一个直接的反转,而不是两个补充:

1111 1111 1111 1111 1111 1111 1100 0011  (32-bit)
                    1111 1111 1100 0011  (16-bit)

在第二个示例中,当您将其向左移动2时,最高位仍然为零。您通过在评论中将数字描述为8位来误导自己。

0000 0000 0000 0000 0000 0000 1111 0000  (32-bit)
                    0000 0000 1111 0000  (16-bit)

答案 1 :(得分:0)

尽量避免使用有符号整数进行按位运算 - 通常它会导致您进入未定义的行为。

这里的情况是您正在使用无符号值并将它们分配给已签名的变量。对于~60,这是undefined behavior。您将其视为-61,因为位模式~60也是-61的二进制补码表示。另一方面,60 << 2出现正确,因为240具有与有符号和无符号整数相同的表示。