Reputation: 41
In this code:
unsigned short int i = 3;
unsigned short int x = 30;
unsigned short int z = (~x) >> i;
On the third row it seems that it first does the shift and THEN the complement (~) even when I use parentheses.
However, the strange result doesn't occur if I replace short
with long
.
It happens both in Windows and in Unix. Why is that?
Upvotes: 2
Views: 129
Reputation: 170084
It performs the operations exactly in the order you prescribed.
However, the operands are not unsigned short ints. Integral promotion turns x
and i
into good old regular signed integers before preforming the operation. To quote the C standard on this:
6.3.1 Arithmetic operands / paragraph 2
The following may be used in an expression wherever an int or unsigned int may be used:
- An object or expression with an integer type (other than int or unsigned int) whose integer conversion rank is less than or equal to the rank of int and unsigned int.
If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int.
And unsigned shorts can fit snugly in a signed integer on the machines you tried.
Furthermore, right shifting a signed integer has implementation defined results for negative values:
6.5.7 Bitwise shift operators / paragraph 5
The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 / 2E2 . If E1 has a signed type and a negative value, the resulting value is implementation-defined.
And ~x
is some negative integer (which one precisely depends on the value representation of signed integers).
All of the above more then likely accounts for you not getting the expected result when converting it back to an unsigned short integer.
Upvotes: 2