为什么相同的位运算会得到不同的结果?
Why the same bitwise operations give different results?
正在尝试关闭 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
适用整数提升规则。
The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand.
初始化的RHS:
unsigned char a = ~0 << 1 >> 1;
将0
转换为int
,然后按位左右移位,最后赋值将结果转换为unsigned char
。这意味着结果将为 255(假设 CHAR_BIT == 8
)。从技术上讲,您有 未定义的行为:
The result of E1 << E2
is E1
left-shifted E2
bit positions; vacated bits are filled with
zeros. If E1
has an unsigned type, the value of the result is E1 × 2E2, reduced modulo
one more than the maximum value representable in the result type. If E1 has a signed
type and nonnegative value, and E1 × 2E2 is representable in the result type, then that is
the resulting value; otherwise, the behavior is undefined.
如果您使用:
,您将避免未定义的行为
unsigned char a = ~0U << 1 >> 1;
'multiple assignments' 版本(避免未定义的行为)等同于:
unsigned char a = (unsigned char)(~0U << 1) >> 1;
它会在重新提升右移类型之前截断左移的结果,并将产生 127 作为结果(仍然假设 CHAR_BIT == 8
)。
正在尝试关闭 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
适用整数提升规则。
The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand.
初始化的RHS:
unsigned char a = ~0 << 1 >> 1;
将0
转换为int
,然后按位左右移位,最后赋值将结果转换为unsigned char
。这意味着结果将为 255(假设 CHAR_BIT == 8
)。从技术上讲,您有 未定义的行为:
The result of
E1 << E2
isE1
left-shiftedE2
bit positions; vacated bits are filled with zeros. IfE1
has an unsigned type, the value of the result is E1 × 2E2, reduced modulo one more than the maximum value representable in the result type. If E1 has a signed type and nonnegative value, and E1 × 2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.
如果您使用:
,您将避免未定义的行为unsigned char a = ~0U << 1 >> 1;
'multiple assignments' 版本(避免未定义的行为)等同于:
unsigned char a = (unsigned char)(~0U << 1) >> 1;
它会在重新提升右移类型之前截断左移的结果,并将产生 127 作为结果(仍然假设 CHAR_BIT == 8
)。