Adobe Interview Question
Software Engineer / Developersunion testendien{
int num;
char byteval[4];
}check;
main()
{
check.num = 1;
(check.num & check.byteval[3])?printf("little endian"):printf("big endian");
}
"Little Endian" means that the low-order byte of the number is stored in memory at the lowest address, and the high-order byte at the highest address. (The little end comes first.) For example, a 4 byte LongInt
Byte3 Byte2 Byte1 Byte0
will be arranged in memory of a 16 bit machine as follows:
Base Address+0 Byte0 Byte1
Base Address+1 Byte2 Byte3
"Big Endian" means that the high-order byte of the number is stored in memory at the lowest address, and the low-order byte at the highest address. (The big end comes first.) Our LongInt, would then be stored as:
Base Address+0 Byte2 Byte3
Base Address+2 Byte0 Byte1
#include <stdio.h>
main()
{
int x=1234;
int Low_Addr = &x; //High_Addr = Low_Addr + 1
if((*Low_Addr) == 12)
Printf("Machine is Big Endian \n");
else
Printf("Machine is little Endian \n");
}
Sunaina gave a good explanation, but the code part has some problems because (*Low_Addr) is always equal to x, i.e. 1234. I copy the solution from wikipedia.org as below.
#include <stdio.h>
int main()
{
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));
}
return(0);
}
The algorithm proposed by "ska" would not work on a 16 or 64-bit architecture.
If we slightly modify the idea proposed by "ska", we will get the simplest implementation.
unsigned long long x = 0x8877665544332211;
if (*(char*)&x == 0x88)
printf("big endian\n");
else
printf("little endian\n");
This will work on 16, 32 and even 64-bit architectures.
Of course, it will fail on 128-bit architectures....
Justification follows:
unsigned long long x = 0x8877665544332211;
64-bit machine:
Big endian:
--------------------
Base Address + 0: 88
Base Address + 1: 77
Base Address + 2: 66
Base Address + 3: 55
Base Address + 4: 44
Base Address + 5: 33
Base Address + 6: 22
Base Address + 7: 11
--------------------
Little endian:
--------------------
Base Address + 0: 11
Base Address + 1: 22
Base Address + 2: 33
Base Address + 3: 44
Base Address + 0: 55
Base Address + 1: 66
Base Address + 2: 77
Base Address + 3: 88
--------------------
32-bit machine:
Big endian:
--------------------
Base Address + 0: 88
Base Address + 1: 77
Base Address + 2: 66
Base Address + 3: 55
---------------------
Base Address + 4: 44
Base Address + 5: 33
Base Address + 6: 22
Base Address + 7: 11
--------------------
Little endian:
--------------------
Base Address + 0: 55
Base Address + 1: 66
Base Address + 2: 77
Base Address + 3: 88
--------------------
Base Address + 0: 11
Base Address + 1: 22
Base Address + 2: 33
Base Address + 3: 44
--------------------
16-bit machine:
Big endian:
--------------------
Base Address + 0: 88
Base Address + 1: 77
--------------------
Base Address + 2: 66
Base Address + 3: 55
--------------------
Base Address + 4: 44
Base Address + 5: 33
--------------------
Base Address + 6: 22
Base Address + 7: 11
--------------------
Little endian:
--------------------
Base Address + 0: 77
Base Address + 1: 88
--------------------
Base Address + 2: 55
Base Address + 3: 66
--------------------
Base Address + 4: 33
Base Address + 5: 44
--------------------
Base Address + 6: 11
Base Address + 7: 22
--------------------
Can anyone please explain what
"if (*(char*)&x == 0x88)" means? We are taking the address of x and what exactly does the *(char*) do? Also, why are we comparing left hand side expression with 0x88?
*(char*) -> converting the pointer of the int to a char pointer, then de-referencing it. On a 32 bit system, this wud return the 1st byte used by x.
Why would Ska's Code not work on 16 and 32 bit m/c...could u please explain??? According to my understanding it should work. correct me with example if i m wrong.
#include<stdio.h>
#define MAX sizeof(int)
typedef union {
int val;
char str[MAX];
}testend;
main()
{
testend tend;
tend.val = 1;
if(tend.str[0] == 1)
printf("little endian");
else
printf("Big endian\n");
}
hey just to answer ur question
(*(char*)&x == 0x88)" means--we r typecasting the int value to char which is just one byte long and which would only take the lowest memory address from the int value . if this value is the highest value part ie 0x88 then we conclude it is big endian else little endian
Have a look at this code.....
int i =1;
(i>>=1) ? puts("Big Endian") :puts("Little Endian");
Almost all the correct approaches have been posted. Just want to post a slightly different one having the use of bitfields. Please confirm if anyone sees it as incorrect.
int x = <no>;
struct bitfield
{
int mybit : 1;
} bf;
bf.mybit = x;
(bf.mybit & 1) ? printf ("little endian") : printf ("big endian");
Almost all the correct approaches have been posted. Just want to post a slightly different one having the use of bitfields. Please confirm if anyone sees it as incorrect.
int x = <no>;
struct bitfield
{
int mybit : 1;
} bf;
bf.mybit = x;
(bf.mybit & 1) ? printf ("little endian") : printf ("big endian");
A good explanation here
- Jack December 10, 2014campuscoke.blogspot.in/2014/12/write-program-to-find-whether-mc-is-big.html