为什么相同的按位运算会产生不同的结果?

时间:2016-05-01 22:57:28

标签: c bitwise-operators unsigned signed

尝试在所有其他位打开的情况下关闭MSB。

unsigned char a = ~0 << 1 >> 1;
printf("a: %d\n", a);

unsigned char b = ~0;
b <<= 1;
b >>= 1;
printf("b: %d\n", b);

打印输出给出:

a: 255
b: 127

1 个答案:

答案 0 :(得分:3)

适用整数促销规则。

  

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

初始化的RHS:

unsigned char a = ~0 << 1 >> 1;

0转换为int,然后按位左右移位,最后分配将结果转换为unsigned char。这意味着结果将是255(假设为CHAR_BIT == 8)。从技术上讲,您有未定义的行为

  

E1 << E2的结果是E1左移E2位位置;腾出的位充满了   零。如果E1具有无符号类型,则结果的值为E1×2 E2 ,减少模数   比结果类型中可表示的最大值多一个。如果E1有签名   类型和非负值,E1×2 E2 在结果类型中可表示,那么   结果价值;否则,行为未定义。

如果您使用了以下内容,则可以避免未定义的行为:

unsigned char a = ~0U << 1 >> 1;

“多个分配”版本(避免未定义的行为)等同于:

unsigned char a = (unsigned char)(~0U << 1) >> 1;

在重新提升右移的类型之前截断左移的结果,结果将产生127(仍然假设为CHAR_BIT == 8)。