C program to check little vs. big endian
Solution 1
In short, yes.
Suppose we are on a 32-bit machine.
If it is little endian, the x
in the memory will be something like:
higher memory
----->
+----+----+----+----+
|0x01|0x00|0x00|0x00|
+----+----+----+----+
A
|
&x
so (char*)(&x) == 1
, and *y+48 == '1'
. (48 is the ascii code of '0')
If it is big endian, it will be:
+----+----+----+----+
|0x00|0x00|0x00|0x01|
+----+----+----+----+
A
|
&x
so this one will be '0'
.
Solution 2
The following will do.
unsigned int x = 1;
printf ("%d", (int) (((char *)&x)[0]));
And setting &x
to char *
will enable you to access the individual bytes of the integer, and the ordering of bytes will depend on the endianness of the system.
Solution 3
This is big endian test from a configure script:
#include <inttypes.h>
int main(int argc, char ** argv){
volatile uint32_t i=0x01234567;
// return 0 for big endian, 1 for little endian.
return (*((uint8_t*)(&i))) == 0x67;
}
Solution 4
Thought I knew I had read about that in the standard; but can't find it. Keeps looking. Old; answering heading; not Q-tex ;P:
The following program would determine that:
#include <stdio.h>
#include <stdint.h>
int is_big_endian(void)
{
union {
uint32_t i;
char c[4];
} e = { 0x01000000 };
return e.c[0];
}
int main(void)
{
printf("System is %s-endian.\n",
is_big_endian() ? "big" : "little");
return 0;
}
You also have this approach; from Quake II:
byte swaptest[2] = {1,0};
if ( *(short *)swaptest == 1) {
bigendien = false;
And !is_big_endian()
is not 100% to be little as it can be mixed/middle.
Believe this can be checked using same approach only change value from 0x01000000
to i.e. 0x01020304
giving:
switch(e.c[0]) {
case 0x01: BIG
case 0x02: MIX
default: LITTLE
But not entirely sure about that one ...
Related videos on Youtube
Comments
-
ordinary almost 2 years
Possible Duplicate:
C Macro definition to determine big endian or little endian machine?int main() { int x = 1; char *y = (char*)&x; printf("%c\n",*y+48); }
If it's little endian it will print 1. If it's big endian it will print 0. Is that correct? Or will setting a char* to int x always point to the least significant bit, regardless of endianness?
-
Sergey Kalinichenko over 11 yearsSee this answer, it may be related.
-
Bo Persson over 11 years@ordinary - Just a note that big endian and little endian are not the only options, that not all data types need to have the same endianness, and that some hardware can be configured at runtime. If you really need to check this, you might have to check more things.
-
mucaho almost 9 yearsIf you have the option, consider bitwise operations on fixed width datatypes to extract/set bits. They are portable according to this answer
-
Eric about 4 yearsGreat endianness demo code for userland and even a kernel module: gitlab.com/eric.saintetienne/endianness
-
young_souvlaki almost 4 yearsWhy use ASCII. Use
'0'
. Why print as a char and not an int. Why start as an int. -
young_souvlaki almost 4 yearsTo answer part of my question, print as
char
so C only reads a byte of data. Start asint
so that we have multiple bytes and can inspect endianness. Cast tochar
now seems unnecessary, just print aschar
.
-
-
Nate-Wilkins over 11 yearsaren't you forgetting ==1 after e.c[0]
-
user1668559 over 11 years@Nate: 1 == 1, 1 != 0, !!1 or 1 is the same. Or am I missing something here?
-
Nate-Wilkins over 11 yearsHmm not sure... This isn't my forte. I saw a similar operation but it had the ==1 at the end. So I'm not sure.
-
user1668559 over 11 years@Nate: Yes. Probably using something like
e = { 0x01020304 };
Thena.c[0] == 1
would be needed asa.c[0]
would be1
or4
on big- vs little. -
Nate-Wilkins over 11 yearsAh yea that would be it.
-
Abin Mathew Abraham over 8 yearsWhat is the significance of the value 48 added to y?
-
Marcus about 8 years@AbinMathewAbraham 48 is the ascii code of '0' :)
-
code4j about 8 yearsI am using MAC OS with intel processors. It is supposed to be Little Endian. However,
1
seems to be a special case because when1
is stored inside the memory, it is in big endian. -
kadina almost 8 yearsNo need to declare as unsigned int. signed int also will do because 1 is positive and even if one bit is reserved for sign, it will be 0 anyway for positive numbers.
-
yano over 6 years@code4j That doesn't make any sense. The CPU architecture isn't going to make an exception simply for a specific value. What you are seeing must be a one byte value, in which case endianess makes no difference. To do an endianess test, you must choose a multi-byte value. Intel chips (AFAIK) are little endian.
-
J...S over 5 yearsCan you tell me why we can't just use
(char)x == 1
? Why do we have to get the address, convert it to achar
pointer and then dereference? Won't this be implicitly done(char)x
is used? -
luizfls over 4 years@J...S I believe
(char)x
would work regardless of endianness. And by "work", I mean it would assign the value1
tox
, so it wouldn't be possible to detect the endianness this way. -
LIU Qingyuan over 3 yearsWhy volatile instead of const?
-
admiring_shannon over 3 yearsI think it is an easy way to avoid any undesired compiler optimization, and actually look at the data in the ram cell to determine the answer.
-
LIU Qingyuan over 3 yearsthx, optimization must be suppressed here.
-
ryyker over 2 yearsregarding your response: "48 is the ascii code of '0'". Would it not be useful to update your answer to "so"
(char*)(&x) == 1, and *y+'0' == '1'
? (nice answer regardless, +1)