有人可以解释一下原因:
x = x << 1;
x = x >> 1;
和:
x = (x << 1) >> 1;
在C中产生不同的答案? x
是* uint8_t *类型(无符号1字节长整数)。例如,当我在第一种情况下传递它128 (10000000)
时,它返回0
(正如预期的那样,最重要的位丢失)但在第二种情况下它返回原始128
。这是为什么?我希望这些表达式是等价的吗?
答案 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结果。