Why does left shift and right shift in one expression give a different result?

Consider the following example:

The first case:

short x=255; x = (x<<8)>>8; cout<<x<<endl; 

Second case:

 short x=255; x = x<<8; x = x>>8; cout<<x<<endl; 

The output in the first case is 255, while in the second case -1. -1 because the output makes sense since cpp performs an arithmetic shift to the right. Here are the intermediate x values ​​to get -1 as output.

 x: 0000 0000 1111 1111 x<<8:1111 1111 0000 0000 x>>8:1111 1111 1111 1111 

Why doesn’t the same mechanism happen in the first case?

+7
c ++ bit-manipulation bit-shift
source share
2 answers

The difference lies in two factors.

  • The C ++ standard does not specify maximum values ​​of integral types. The standard defines only the minimum size of each integer type. On your platform, short is a 16-bit value, and int is at least a 32-bit value.

  • The second factor is two-component arithmetic.

In your first example, the short value naturally advances to int , which is at least 32 bits, so the left and right shifts work for int before returning to short .

In your second example, after the first operation with the left shift, the resulting value is again converted back to short , and due to two arithmetic additions, it becomes negative. The right shift ends with a sign expressing a negative value, which leads to a final result of -1.

+12
source share

What you just noticed is an extension of the sign :

Sign expansion is an operation in computational arithmetic to increase the number of bits of a binary number while maintaining the sign of the number (positive / negative) and value. This is done by adding digits to the most significant side of the number, following a procedure that depends on the particular number name used.

For example, if six bits are used to represent the number β€œ00 1010” (decimal positive 10), and the character expansion operation increases the word length to 16 bits, then the new representation is simply β€œ0000 0000 0000 1010”. Thus, both the value and the fact that the value is positive are retained.

If ten bits are used to represent the value "11 1111 0001" (decimal minus 15) using two additions, and this character is expanded to 16 bits, the new representation is "1111 1111 1111 0001". Thus, filling the left side with units, the negative sign and the value of the original number are saved.

You go completely to the point where your short becomes negative, and when you then go back, you get a sign extension.

This does not occur in the first case, since the shift does not apply to the short. It applies to 255 , which is not a short but default integral type (possibly int ). It only gets after moving it back:

 on the stack: 0000 0000 0000 0000 0000 0000 1111 1111 <<8 on the stack: 0000 0000 0000 0000 1111 1111 0000 0000 >>8 on the stack: 0000 0000 0000 0000 0000 0000 1111 1111 convert to short: 0000 0000 1111 1111 
+1
source share

All Articles