2

有人可以解释一下为什么:

x = x << 1;
x = x >> 1;

和:

x = (x << 1) >> 1;

在 C 中产生不同的答案?x是 *uint8_t* 类型(无符号 1 字节长整数)。例如,当我128 (10000000)在第一种情况下传递它时,它会返回0(正如预期的那样,最高有效位会掉出来),但在第二种情况下,它会返回原始的128. 这是为什么?我希望这些表达式是等价的?

4

2 回答 2

13

这是由于整数提升,在这两种情况下,按位移位的两个操作数都将提升为int。在第二种情况下:

x = (x << 1) >> 1;

的结果x << 1将是一个int ,因此移位的位将被保留并可作为int用于下一步,这将再次将其移回。在第一种情况下:

x = x << 1;
x = x >> 1;

当您重新分配给您时,x您将丢失额外的位。从草案 C99 标准部分6.5.7 Bit-wise shift operators它说:

对每个操作数执行整数提升。

整数提升在6.3.1.1 布尔、字符和整数部分第2段中介绍,其中说:

如果一个 int 可以表示原始类型的所有值,则将该值转换为 int;否则,它将转换为无符号整数。这些被称为整数促销。48)

最后一点为什么从int256uint8_t的转换给我们0?转换在“转换”部分下的有6.3.1.3 符号和无符号整数部分中进行了介绍,并说:

否则,如果新类型是无符号的,则通过在新类型中可以表示的最大值的基础上反复加减一,直到该值在新类型的范围内。49)

所以我们有256 - (255+1)which is 0

于 2014-03-28T00:42:22.693 回答
6

当您进行位移时,结果将提升为int. 在第一个示例中,您每次都将 int 转换回 uint8_t,并丢失中间数据。但是在第二个示例中,当您移回时,您会保留 int 结果。

于 2014-03-28T00:42:30.467 回答