liitle endian

R

raghu

Is it possible to know whether a system is little endian or big endian
by writing a C program? If so, can anyone please give me the idea to
approach...

Thanks a ton.

Regards,
Raghu
 
R

Richard Heathfield

raghu said:
Is it possible to know whether a system is little endian or big endian
by writing a C program?

If you're careful, it's possible for it not to matter.
 
J

jaysome

raghu said:

Yes.

If you're careful, it's possible for it not to matter.

Yes. And some might even exercise poetic license and rephrase your
answer to something like this:

If you're really carefull, it's guaranteed for it not to matter.
 
R

Richard Tobin

raghu said:
Is it possible to know whether a system is little endian or big endian
by writing a C program? If so, can anyone please give me the idea to
approach...

The essence of endianness is the question of what happens when you use
an address to access objects of two different sizes. When you fetch
the smaller object, do you get the big end or the little end of larger
object?

In C, you can legally treat any object as a sequence of bytes, so you
can indeed portably determine the endianness (though it's not guaranteed
to be either big- or little-endian - it could be something stranger).

-- Richard
 
H

huuguanghui

#include <stdio.h>

struct test
{
unsigned short a;
unsigned short b;
};

int main()
{
struct test t = {0, 1};
printf("%d\n", t);
}

if the output is 1, your system is big endian
if the output is 65536, your system is little endian
 
B

Barry

#include <stdio.h>

struct test
{
unsigned short a;
unsigned short b;
};

int main()
{
struct test t = {0, 1};
printf("%d\n", t);
}

if the output is 1, your system is big endian
if the output is 65536, your system is little endian

My compiler output is 0, I guess its un-endian.
 
J

Joe Wright

jaysome said:
Yes. And some might even exercise poetic license and rephrase your
answer to something like this:

If you're really carefull, it's guaranteed for it not to matter.
Hi Jay, tell me how.

I have Standard C programs which must read, write and manipulate .DBF
data files. The .DBF file contains interesting data in 16 and 32 bit
integers in little endian format. My C programs must perform identically
on Sparc (big endian) and x86 (little endian) boxes. How shall I do that
without knowing and caring about endianess of the box?

I agree with Richard that it usually shouldn't matter but even being
really careful, I wonder the nature of your guarantee; Money Back?,
Double Your Money Back? :)
 
E

Ernie Wright

raghu said:
Is it possible to know whether a system is little endian or big
endian by writing a C program? If so, can anyone please give me the
idea to approach...

The following is fairly common:

unsigned int i = 0x04030201;
char *p = ( char * ) &i;

switch ( p[ 0 ] ) {
case 1: /* Intel x86, Windows, little-endian */ ...
case 4: /* Motorola 68K, big-endian */ ...
default: /* something else */ ...
}

This assumes that int is 32 bits, which isn't guaranteed. It won't work
on a Cray, or in most compilers for 16-bit CPUs, for example. But in
most cases you can first examine the values of UINT_MAX, ULONG_MAX and
USHRT_MAX to find a 32-bit integer type and use that type in the test.

- Ernie http://home.comcast.net/~erniew
 
R

Richard Heathfield

Joe Wright said:

I have Standard C programs which must read, write and manipulate .DBF
data files. The .DBF file contains interesting data in 16 and 32 bit
integers in little endian format. My C programs must perform identically
on Sparc (big endian) and x86 (little endian) boxes. How shall I do that
without knowing and caring about endianess of the box?

Do you have 8 bits per byte? Looks like it, from your platform list. So it's
easy - to read a 16-bit integer in little-endian format, first read the
first 8 bits, and then read the second eight bits. Multiply one or other of
them (I can never remember which, but it's not going to take you all day to
find out by a process of elimination) by 256, add the other one, and you're
done. For 32-bit integers, do this rather more often and with bigger
numbers. :)
 
C

CBFalconer

Joe said:
jaysome wrote:
.... snip ...
Hi Jay, tell me how.

I have Standard C programs which must read, write and manipulate
.DBF data files. The .DBF file contains interesting data in 16 and
32 bit integers in little endian format. My C programs must perform
identically on Sparc (big endian) and x86 (little endian) boxes.
How shall I do that without knowing and caring about endianess of
the box?

I agree with Richard that it usually shouldn't matter but even
being really careful, I wonder the nature of your guarantee; Money
Back?, Double Your Money Back? :)

For example (untested):

/* convert 4 octet little endian to integer */
/* assumes each byte contains one octet */
/* also that UINT_MAX is >= 2 ** 32 */
/* (else use longs, which will always work) */
unsigned int convert4(const char *s) {
unsigned int i, val;

for (i = val = 0; i < 4; i++)
val = val * 256 + ((s & 0ffh) << (8 * i));
return val;
}

If you need signed ints, test the final result for exceeding
MAX_INT. Note that this will work even if unsigned ints contain
padding bits. The endianess of your system doesn't matter.
 
E

Ernie Wright

Joe said:
I have Standard C programs which must read, write and manipulate .DBF
data files. The .DBF file contains interesting data in 16 and 32 bit
integers in little endian format. My C programs must perform identically
on Sparc (big endian) and x86 (little endian) boxes. How shall I do that
without knowing and caring about endianess of the box?

Something like this.

int getI4_L( FILE *fp )
{
int i, c, n = 0;

for ( i = 0; i < 4; i++ ) {
c = fgetc( fp );
if ( c == EOF )
return handleError( fp );
n |= c << ( i * 8 );
}
return n;
}

To read big-endian 4-byte integers,

int getI4_B( FILE *fp )
{
...
for ( i = 3; i >= 0; i-- ) {

- Ernie http://home.comcast.net/~erniew
 
B

Bill Pursell

raghu said:
Is it possible to know whether a system is little endian or big endian
by writing a C program? If so, can anyone please give me the idea to
approach...

Other people have suggested methods for checking the value
of one of the bytes of a multi-byte value, and that is a reasonable
techinque, but for most hosted systems you can also
look in the system headers for something like:

#define BYTE_ORDER LITTLE_ENDIAN


When you're writing the program, if you need to know, you
can tell by doing something like:
#if BYTE_ORDER == LITTLE_ENDIAN
do_little_endian_processing();
#else
do_big_endian_processing();
#endif

(Note that this example assumes that
there is no other byte ordering, which is absurd
since it is perfectly reasonable for someone to
build a machine in which a 4 byte integer is ordered
0,3,1,2, or some other permutation.)

Also, consider using the htonl() family of functions.
 
B

Barry Schwarz

#include <stdio.h>

struct test
{
unsigned short a;

And if the compiler decided to insert some padding?
unsigned short b;
};

int main()
{
struct test t = {0, 1};
printf("%d\n", t);

Why would you assume that a struct is passed to a variadic function
the same way an int would be? Why would you assume 2 *
sizeof(unsigned short) is equal to sizeof(int)?
}

if the output is 1, your system is big endian
if the output is 65536, your system is little endian

Since you have invoked undefined behavior, you have determined
nothing.


Remove del for email
 
J

Joe Wright

Richard said:
Joe Wright said:



Do you have 8 bits per byte? Looks like it, from your platform list. So it's
easy - to read a 16-bit integer in little-endian format, first read the
first 8 bits, and then read the second eight bits. Multiply one or other of
them (I can never remember which, but it's not going to take you all day to
find out by a process of elimination) by 256, add the other one, and you're
done. For 32-bit integers, do this rather more often and with bigger
numbers. :)
Richard, you misunderstand I think. I can easily convert between Sparc
and x86 integers. The question was "Shall I?" and how to know.

Networking libraries may present us htonl() and ntohl() but, alas, they
are not C.
 
E

Eric Sosman

Joe said:
Richard, you misunderstand I think. I can easily convert between Sparc
and x86 integers. The question was "Shall I?" and how to know.

You needn't know or care: Richard's method works unchanged
on Little-, Big-, Middle-, and Mixed-Endian platforms. (Extra
credit: Devise a corresponding "endian-oblivious" scheme for
writing integers.)

Are you worried about offending the Little Tin God? Given
that there's I/O going on, it's dollars to doughnuts that your
CPU is loafing anyhow and could afford to do a half-dozen FFTs
between reads without slowing anything down.
 
P

P.J. Plauger

Other people have suggested methods for checking the value
of one of the bytes of a multi-byte value, and that is a reasonable
techinque, but for most hosted systems you can also
look in the system headers for something like:

#define BYTE_ORDER LITTLE_ENDIAN


When you're writing the program, if you need to know, you
can tell by doing something like:
#if BYTE_ORDER == LITTLE_ENDIAN
do_little_endian_processing();
#else
do_big_endian_processing();
#endif

(Note that this example assumes that
there is no other byte ordering, which is absurd
since it is perfectly reasonable for someone to
build a machine in which a 4 byte integer is ordered
0,3,1,2, or some other permutation.)

At a stretch, yes. Nevertheless, practically all computers today
use either {0 1 2 3} or {3 2 1 0}. Neverthe-nevertheless, the
original PDP-11 C compiler represented 32-bit integers as
{2 3 0 1}.
Also, consider using the htonl() family of functions.

Exactly. The presenting problem is assembling bytes from a
stream to make an internal integer, and/or emitting bytes
to a stream given an internal integer. You don't need to
know the internal properties of the host architecture to
do that job.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
S

Stephen Sprunk

Joe Wright said:
Richard, you misunderstand I think. I can easily convert between Sparc
and x86 integers. The question was "Shall I?" and how to know.

You don't need to know. The problem is reading from the file as a
multi-byte object and then trying to determine if you need to adjust it.
The solution is reading one byte at a time, so that what you do with the
bytes afterwards doesn't vary between platforms.
Networking libraries may present us htonl() and ntohl() but, alas,
they are not C.

Even if available, htonl() and ntohl() are the exact opposite of what
the OP wants. They convert between system endianness and "network byte
order", which is big endian. Since his files are stored in
little-endian format, these functions will manage to give him the wrong
results on _every_ platform.

If you're looking for a fast, non-portable solution, I'd look for
something like Linux's <endian.h> and <byteswap.h>.

The shift-and-add method is the portable way, but it's likely to be much
slower unless the compiler has a specific optimization to detect and
replace that code pattern.

S
 
D

dick

easy.

short int a=0x1234;

if( (*(char*)&a)=='\x12')
{
// big endian
}
else
{
// little endian
}

good enough?
 
K

Keith Thompson

dick said:
easy.

short int a=0x1234;

if( (*(char*)&a)=='\x12')
{
// big endian
}
else
{
// little endian
}

good enough?

Please don't top-post. Read the following:

http://www.caliburn.nl/topposting.html
http://www.cpax.org.uk/prg/writings/topposting.php

And since "Please don't top-post" appears to be the most regularly
posted advice in this newsgroup these days, I'll also advise you to
follow a newsgroup for a while before posting. (Of course, anyone who
needs this advice won't read it -- sigh.)

No, it's not good enough in general. You're assuming that short is 2
bytes, and that a byte is 8 bits. Neither is guaranteed by the
language. I've worked on systems where short is 32 or 64 bits.
 
D

dick

easy.

short int a=0x1234;

if(! (*(char*)&a)=='\x34')
{
// big endian
}

else
{
// little endian

}

good enough?

- Hide quoted text -
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,228
Latest member
MikeMichal

Latest Threads

Top