比特转移混乱

时间:2017-11-07 05:25:38

标签: c bit

为什么0x56 << 2不等于0x58

0x560 1 0 1 0 1 1 0,因此向左移动2位

         0 1 0 1 1 0 0 0

010110000x58。但它不是正确答案0x158。那么我在这里缺少什么?

即使我这样做:

int main(){
    unsigned char a;
    a=0x56;
    printf("%x",a<<2);  // I am expecting the output to be 58 here.
} 

为什么打印158. 为什么不考虑仅仅8位?

3 个答案:

答案 0 :(得分:8)

位移运算符<style> .float_center { display: flex; justify-content: center; } </style> <<仅适用于整数。所以当你在这里使用它时,它们首先被提升为>>(大于1个字节),然后完成转换。您可以看到6.5.7p3

标准中提到了它
  

对每个操作数执行整数提升。结果的类型是提升的左操作数的类型。

int(带printf和格式说明符)也期望参数为%x类型。所以没有降级,你得到unsigned int

如果您希望结果只有一个字节,则应将结果转换回0x158 as -

unsigned char

或者您可以声明另一个变量printf("%x", (unsigned char)(a << 2)); 并打印 -

b

您可以看到演示here

答案 1 :(得分:2)

C11 6.5.7按位移位运算符

第2段:

  

每个操作数都应具有整数类型。

第3段:

  

对每个操作数执行整数提升。类型   结果是提升左操作数的结果。如果值   右操作数为负数或大于或等于宽度   在提升的左操作数中,行为未定义。

因此,由于整数提升,我们需要两个操作数int类型。

答案 2 :(得分:2)

来自C Standards#6.5.7

  

对每个操作数执行整数提升。结果的类型是提升的左操作数的类型。如果右操作数的值为负或大于或等于提升的左操作数的宽度,则行为未定义。

所以当你这样做时:

a<<2;

a被提升为整数,然后完成移位操作。在printf()中,您使用%x格式说明符输出无符号十六进制整数,因此输出为158