我在c:
中具有以下代码 unsigned int a = 60; /* 60 = 0011 1100 */
int c = 0;
c = ~a; /*-61 = 1100 0011 */
printf("c = ~a = %dn", c );
c = a << 2; /* 240 = 1111 0000 */
printf("c = a << 2 = %dn", c );
第一个输出是-61,而第二个输出为240。为什么第一个printf计算两者的补充1100 0011,而第二个则仅将1111 0000转换为其十进制等效的数字?
您假设int
只有8位宽。在您的系统上可能不是这种情况,它可能使用16或32位用于int
。
在第一个示例中,所有位倒转。这实际上是直截了当的,而不是两个的补充:
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)
尝试避免使用签名的整数进行刻度操作 - 通常会导致您陷入不确定的行为。
这里的情况是,您正在使用未签名的值并将其分配给签名变量。对于~60
,这是未定义的行为。您将其视为-61,因为位模式~60
也是-61的两个组合表示形式。另一方面,60 << 2
出现正确,因为240
具有与签名和未签名的整数相同的表示。