简体   繁体   中英

Combine 2 bytes into a short int in C

I am receiving a short int via network packet, which means it would come as 2 bytes in network byte order (big endian).

I would like to combine the two bytes I received into a short int variable on my machine, which is little endian byte order.

Example:

short int test = 400; //0x190 in big endian, 0x9001 in little endian
char testResponse[2] = {0x01, 0x90};
//here is my attempt
short int result = testResponse[1] << 8 | testResponse[0];
printf("%d\n", result); //-28671 when expecting 400

Any help would be appreciated!

#include <arpa/inet.h>
#include <string.h>

int16_t result;
memcpy(&result, testResponse, sizeof(int16_t));
result = (int16_t)ntohs((uint16_t)result);

Some platforms, such as 32-bit arm, don't allow unaligned accesses. So use memcpy to get it into a correctly sized int before calling ntoh.

You've confused the indices. The number is 0x0190 in little endian, but your code calculates the big-endian number, which is 0x9001 , which, in signed short will also cause integer overflow upon left-shift to the sign bit.

The code indeed isn't very portable as char might be signed or unsigned. While it might be true that majority of architectures have unsigned chars, the truth is that majority of C programs are written for signed char architecture - the x86. There the fact that 0x90 is sign-extended might cause wild unexpected results.

Thus more portable would be

char testResponse[2] = {0x01, 0x90};
unsigned int tmp = (unsigned)testResponse[0] << 8 | (unsigned)testResponse[1];
short result = tmp;  // implementation-defined behaviour
printf("%d\n", result); // 400

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM