Since a
has a negative value,
unsigned int c = a << 16 | b;
results in undefined behavior.
From the C99 standard (emphasis mine):
6.5.7 Bitwise shift operators
4 The result of E1 << E2
is E1
left-shifted E2
bit positions; vacated bits are filled with zeros. If E1
has an unsigned type, the value of the result is E1
x 2
E2
, reduced modulo one more than the maximum value representable in the result type. If E1
has a signed type and nonnegative value, and E1
x 2
E2
is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.
You can explicitly cast the signed short
to unsigned short
to get a predictable behavior.
#include <stdio.h>
int main()
{
signed short a, b;
a = -16;
b = 340;
unsigned int c = (unsigned short)a << 16 | (unsigned short)b;
signed short ar, br;
ar = c >> 16;
br = c & 0xFFFF;
printf("ar: %hd, br: %hd\n", ar, br);
}
Output:
ar: -16, br: 340