Doe Joe
Doe Joe

Reputation: 137

C little endian but produce big endian result?

I just did a small experiment on the Raspberry Pi I'm working on with the following code:

//tutorialspoint.com/unix_sockets/network_byte_orders.htm

#include <stdio.h>

int main(int argc, char **argv) {

   union {
      short s;
      char c[sizeof(short)];
   }un;

   un.s = 0x0102;

   if (sizeof(short) == 2) {
      if (un.c[0] == 1 && un.c[1] == 2)
         printf("big-endian\n");

      else if (un.c[0] == 2 && un.c[1] == 1)
         printf("little-endian\n");

      else
         printf("unknown\n");
   }
   else {
      printf("sizeof(short) = %d\n", sizeof(short));
   }

   exit(0);
}

The result that I got was little endian.

Now when i convert an integer to byte array, the result which came out is in big endian

unsigned char c[4];
int num = 170; // suppose to give 0000 0000 0000 00AA
memcpy(c, (char*)&num, sizeof(int));
printf("c[0] = %04x \n", c[0]);
printf("c[1] = %04x \n", c[1]);
printf("c[2] = %04x \n", c[2]);
printf("c[3] = %04x \n", c[3]);
memcpy((char *)&num, c, sizeof(int));
printf("%d\n", ntohl((long)num));

Output:

c[0] = 00aa

c[1] = 0000

c[2] = 0000

c[3] = 0000

-1442840576

I had to do a shift in order to get it to become little endian

//c[0] = (num >> 24) & 0xFF;
//c[1] = (num >> 16) & 0xFF;
//c[2] = (num >> 8) & 0xFF;
//c[3] = num & 0xFF;

Now I am confused if my raspberry pi is in little endian or big endian?

In addition, I'm going to pass this data through a socket, so do i need to make sure that it is in network byte order or is it okay as long as i standardized which endian i am going to use across all devices i'm trying to communicate with?

PS. In addition, If I need to manually convert all integers in an integer array from little endian to big endian, what is the approach I should do? Most of the solutions I find online are only converting an integer and not an integer array.

Upvotes: 0

Views: 620

Answers (2)

rghome
rghome

Reputation: 8819

It is little-endian in both cases.

In your first case, the least significant byte is 2 and that matches c[0] - little-endian.

In your second case, the least significant byte is 170 (all others are zero) and that matches c[0] - little-endian.

If you are copying data over a socket, then you just need to make sure the data format is consistent. It doesn't matter what it is.

For copying an array of data, just do the same thing as a single item, but repeat it.

Upvotes: 4

Michael
Michael

Reputation: 58427

int num = 170; // suppose to give 0000 0000 0000 00AA

No. It's supposed to give you AA, 00, 00, 00 (or AA, 00, 00, 00, 00, 00, 00, 00 if int is 64-bit).
In a little-endian layout the least significant byte is stored at the lowest address. The least significant byte of 0x000000AA (170) is 0xAA.

Upvotes: 1

Related Questions