I have an unsigned char array with 2 elements that represents a signed integer. How can I convert these 2 bytes into a signed integer?
Edit: The unsigned char array is in little endian
For maximum safety, use
int i = *(signed char *)(&c[0]);
i *= 1 << CHAR_BIT;
i |= c[1];
for big endian. Swap c[0] and c[1] for little endian.
(Explanation: we interpret the byte at c[0] as a signed char, then arithmetically left shift it in a portable way, then add in c[1].)
unsigned char to signed char. I'm using a pointer cast to reinterpret the bit pattern as signed char, then promoting to int.(int16_t *)c may induce SIGBUS on many RISC processor, and reduce performance on IA86 architecture.-O2. Removed the pointer trick.wrap them up in a union:
union {
unsigned char a[2];
int16_t smt;
} number;
Now after filling the array you can use this as number.smt
short to int conversion is well-defined. Though I'd recommend using int16_t instead of short.It depend of endianness. Something for big endian :
unsigned char x[2];
short y = (x[0] << 8) | x[1]
Something for little endian :
unsigned char x[2];
short y = (x[1] << 8) | x[0]
char is signed (x[0] and x[1] will be sign-extended, so if the least significant one is negative, the upper byte will be set to all 1s by the bitwise OR).The portable solution:
unsigned char c[2];
long tmp;
int result;
tmp = (long)c[0] << 8 | c[1];
if (tmp < 32768)
result = tmp;
else
result = tmp - 65536;
This assumes that the bytes in the array represent a 16 bit, two's complement, big endian signed integer. If they are a little endian integer, just swap c[1] and c[0].
(In the highly unlikely case that it is ones' complement, use 65535 instead of 65536 as the value to subtract. Sign-magnitude is left as an exercise for the reader ;)
c[0] and c[1] are positive numbers between 0 and 255, tmp is a positive number in range 0 to 65535. The only negative number is produced in the final subtraction - there is no chance of unwanted sign extension.
unsigned charcould represent a signed integer. You should be more specific on that.