有人可以解释一下为什么:
x = x << 1;
x = x >> 1;
和:
x = (x << 1) >> 1;
在 C 中产生不同的答案?x
是 *uint8_t* 类型(无符号 1 字节长整数)。例如,当我128 (10000000)
在第一种情况下传递它时,它会返回0
(正如预期的那样,最高有效位会掉出来),但在第二种情况下,它会返回原始的128
. 这是为什么?我希望这些表达式是等价的?
有人可以解释一下为什么:
x = x << 1;
x = x >> 1;
和:
x = (x << 1) >> 1;
在 C 中产生不同的答案?x
是 *uint8_t* 类型(无符号 1 字节长整数)。例如,当我128 (10000000)
在第一种情况下传递它时,它会返回0
(正如预期的那样,最高有效位会掉出来),但在第二种情况下,它会返回原始的128
. 这是为什么?我希望这些表达式是等价的?
这是由于整数提升,在这两种情况下,按位移位的两个操作数都将提升为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)
最后一点为什么从int值256
到uint8_t的转换给我们0
?转换在“转换”部分下的有6.3.1.3
符号和无符号整数部分中进行了介绍,并说:
否则,如果新类型是无符号的,则通过在新类型中可以表示的最大值的基础上反复加减一,直到该值在新类型的范围内。49)
所以我们有256 - (255+1)
which is 0
。
当您进行位移时,结果将提升为int
. 在第一个示例中,您每次都将 int 转换回 uint8_t,并丢失中间数据。但是在第二个示例中,当您移回时,您会保留 int 结果。