Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
572 views
in Technique[技术] by (71.8m points)

c - Why does combining two shifts of a uint8_t produce a different result?

Could someone explain me why:

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

and:

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

produce different answers in C? x is a *uint8_t* type (unsigned 1-byte long integer). For example when I pass it 128 (10000000) in the first case it returns 0 (as expected most significant bit falls out) but in the second case it returns the original 128. Why is that? I'd expect these expressions to be equivalent?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is due to integer promotions, both operands of the bit-wise shifts will be promoted to int in both cases. In the second case:

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

the result of x << 1 will be an int and therefore the shifted bit will be preserved and available to the next step as an int which will shift it back again. In the first case:

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

when you assign back to x you will lose the extra bits. From the draft C99 standard section 6.5.7 Bit-wise shift operators it says:

The integer promotions are performed on each of the operands.

The integer promotions are covered in section 6.3.1.1 Boolean, characters, and integers paragraph 2 which says:

If an int can represent all values of the original type, the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions.48)

The last piece of this why does the conversion from the int value 256 to uint8_t give us 0? The conversion is covered in section 6.3.1.3 Signed and unsigned integers which is under the Conversions section and says:

Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.49)

So we have 256 - (255+1) which is 0.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...