LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   problem in understanding little endian/big endian machine program (http://www.linuxquestions.org/questions/programming-9/problem-in-understanding-little-endian-big-endian-machine-program-425370/)

 indian 03-16-2006 08:52 AM

problem in understanding little endian/big endian machine program

Hi, I saw a program in C which tells whether the machine is little endian or big endian but I amnot able to understand it.

Code:

```#define LITTLE_ENDIAN 0 #define BIG_ENDIAN    1 int machineEndianness() {   int i = 1;   char *p = (char *) &i;   if (p[0] == 1) // Lowest address contains the least significant byte       return LITTLE_ENDIAN;   else       return BIG_ENDIAN; }```
I am not able to understand the colored line. the code is here..

I also got one more code doing same thing which too Iam not able to understand.

Code:

```#include <stdio.h> main () {   union   {       char c[4];       int i;   } stuff;   stuff.i = 0;   stuff.c[0] = 1;   stuff.i <<= 8;   if (stuff.i) printf("little endian\n");   else printf("big endian\n"); }```
I will really appreciate if someone can explain me what is happening.

Regards

I'll try to explain the best I can:

On computers, integers are stored in (machine) words, units of four bytes.

Code:

```+--+--+--+--+ |b1|b2|b3|b4| +--+--+--+--+```
(where each byte is 8 bits).

On little-endian machines, the least significant bits (that is, the one that code for 1, 2, 4, 8, ...) are in b1, whereas on big-endian machines the least significant bits are in b4.

The code assumes that the address of i is the same as the address of b1. So if you interpret &b1 as a char pointer, you're going to see b1 instead of (b1,b2,b3,b4). So by looking at b1, the code can detect whether the machine is little or big endian, by seeing if b1 is zero or not.

 tuxombie 04-19-2006 11:47 AM

hi

yeah in big endian the bytes are ordered differently. i ll try speculating on the first code bit here.

int i = 1;
char *p = (char *) &i;
if (p[0] == 1) // Lowest address contains the least significant byte
return LITTLE_ENDIAN;
else
return BIG_ENDIAN;

here we have the integer 1. in binary,this would be 01.

the least significant digit is 1 here. in little endian computers, we would read this as our first char.

a[0]=1, a[1]=0.

in big endian computers we will have

a[0]=0, a[1]=1.

This was a very nice post. I should have looked up lq before tearing myself apart with this endianness problem a few weeks ago :). anyway, i am going to start a thread explaining my difficulties and how it has been overcome.

 dmail 04-19-2006 12:21 PM

You are correct in what you are saying but the following can be taken the wrong way.

Quote:
 ...here we have the integer 1. in binary,this would be 01. the least significant digit is 1 here. in little endian computers, we would read this as our first char. a[0]=1, a[1]=0. in big endian computers we will have a[0]=0, a[1]=1.
Just so this doesn't confuse anybody who could be mistaken as if each bit is a char. Your example of the binary number 01 and then using chars which are 0 and 1 could have been clearer using another number something like 256 etc as this exstends beyond the first byte.

In addittion you should point out that your ints are 16bit ints. :)

 MichaelZ 04-19-2006 01:27 PM

Hello,

Just a couple of documents that could be useful to better understand the little/big endian concept:

http://en.wikipedia.org/wiki/Endianness
http://www.webopedia.com/TERM/b/big_endian.html
http://www.noveltheory.com/TechPapers/endian.asp

Best wishes,
Michael

 tuxombie 04-19-2006 02:42 PM

[QUOTE=dmail]You are correct in what you are saying but the following can be taken the wrong way.

Yeah I know, and I am not too familiar with it myself, which was why I said 'speculate'. But the idea is that.

Two weeks ago, I had to transfer a bunch of binary files from my office Desktop to the super-computer where I run simulations on flames. Unfortunately, I have been here only a few months, and there is very little documentation explaining this problem. It is mentioned, but in a very rudimentary way, but there is little that tells how to solve it.

Now, as these binary input files exist on an intel comp, where presumably simulations had been run before, they were in little endian form. It took me a while to even discover the problem.

I guess, modifying a bit of code is the way to go, so that the bytes can be swapped there, but I needed (and still need!) quick results. Furthermore, several of these compilers have this option to give it as an option in the compiler flags. But the stupid IBM mplxf95 compiler doesn't.

I resolved the problem with the intel ifort compilers, which have this option. I very strongly recommend it for anyone doing fortran stuff. But there are catches which depend on the system, such as defining the type; and it took me a while and some trial and error and reading the manpages to get this to work.

real*8:: time, time_save, tstep
real*8,dimension(1216,244,1,5) :: yspecies
real*8, dimension(1216,244,1) :: temp, pressure

The reals in IBM are real*8. Just real will not work. The reader is referred to the intel fortran man pages on the details of achieving the conversion. Anyway, the story is to read the data with a small code as little endian and write it as big endian.

 tuxombie 04-19-2006 02:50 PM

I may also add that the icc and ifort compilers install 'easily' only for the rpm linii. I have Debian in the office computer and it was very difficult to install it. The conversion was done in an Suse machine.

We can make it install on a debian machine, but it is slightly non-trivial. There are posts explaining this (I am too lazy to search at the moment and put the links here).

 All times are GMT -5. The time now is 03:33 PM.