为什么组合uint8_t的两个班次产生不同的结果?

时间:2014-03-28 00:40:36

标签: c bit-shift integer-promotion

有人可以解释一下原因:

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

和:

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

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

2 个答案:

答案 0 :(得分:12)

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

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

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

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

当您分配回x时,您将失去额外的位。从draft C99 standard部分6.5.7 Bit-wise shift operators开始,它说:

  

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

整数促销活动包含在6.3.1.1 布尔,字符和整数 2 中,其中包含:

  

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

为什么从 int 256 uint8_t 的转换为我们提供了0?转换在6.3.1.3 签名和无符号整数部分中介绍,该部分位于转化部分下,并说:

  

否则,如果新类型是无符号的,则通过重复添加或转换该值   减去一个可以在新类型中表示的最大值   直到该值在新类型的范围内。 49)

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

答案 1 :(得分:6)

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