Endianity

i wonder about endianity issue with double/float…
is it a stupid question ?

i have no idea of how they are laid in memory and write on disk.
could someone tell me ?

Mensaje citado por: Lloyd Dupont <Lloyd.Dupont at wanadoo.fr>:

i wonder about endianity issue with double/float…
is it a stupid question ?

No, absolutely no.

i have no idea of how they are laid in memory and write on disk.
could someone tell me ?

While IEEE define how float should be and so, they “forgot” to define how they
should be stored… so you have to use try&error method.

              Miguel Angel Blanch Lardin

         -- http://www.arianne.cx -- Arianne --

The free open source massively multiplayer online role playing game

nuclear cia fbi spy password code encrypt president bomb iran irak korea cuba
Ala yihad mosad kgb free freedom human rights yugoslavia kosovo ebola dna

                -- Echelon must die --

i wonder about endianity issue with double/float…
is it a stupid question ?

No but somewhat offtopic. SDL does not provide any facilities for converting
floating point values between machines. If you don’t know what you are doing,
use integers and strings in your files (and network protocols)

On x86 based systems, the low order bytes are stored first (in memory). This
is called little-endian. On PowerPC based systems, I think they are stored
high order bytes first. This is big endian.

For example, a short int (16-bit) number would store the least significant
8-bits first and the most signifcant 8-bits first. So a number $FF00 (in
hex) would be stored $00 for the first byte, and $FF on the second byte on
x86 systems, and $FF on the first byte and $00 on the second byte for
Motorolla (powerPC) based systems.

Everytime you deal with a data type like short or long, and perform
operations on it its always interpreted to be a big endian system. So if you
AND a short int (16-bits) with a byte (8-bits), the byte AND’d will be
performed always on the least significant byte of the short int.

Its only from reading or writing to memory (or harddisk, or whatever) where
you have to worry about the order of the bytes. In fact, the only reason you
would ever have to worry is if your sharing data between one big-endian
system and another little-endian system. Such an incident would happen in
SDL_Network or whatever, since it has cross-platform network code. Also it
would be important when say you save data for one game under the Mac and
load it under the PC.

Hmm, that probably sounds confusing. I recommending reading a good
binary/hex tutorial.

Matt> i wonder about endianity issue with double/float…

is it a stupid question ?

i have no idea of how they are laid in memory and write on disk.
could someone tell me ?

thanks for all your answer.

i guess i had to look at SDL_net source code.

i wonder about endianity issue with double/float…
is it a stupid question ?

i have no idea of how they are laid in memory and write on disk.
could someone tell me ?

Just let me add an answer. I used to work on 3D graphic file formats imports
from Amiga, Mac and other big endian workstations.
I hope the following will help you :

the IEEE floats are 4bytes wide using this way ( I may be wrong )
1     digit for the sign
8     for the exponent part
23   for the value corps                        ( Oups, my english level

is decreasing … )

In fact, THEY ARE ALLWAYS STORED AS DONE FOR A DWORD. but THEY ALWAYS

FOLLOW IEEE SPECS.

That means you need to reverse datas in memory more or less this way :

void    bigToLittle(float* value)                /* could be called

‘littleToBig’ too … :slight_smile: /
{
unsigned char tmp;
unsigned char
ptr;

    ptr = (char*)(void*)value;

    /* Now me can switch the datas */
    tmp       = ptr[0];
    ptr[0]    = ptr[3];
    ptr[3]    = tmp;
    tmp       = ptr[1];
    ptr[1]    = ptr[2];
    ptr[2]    = tmp;

    /* absolutely not optimized .......... */
    /* never mind ... ;-) */

}

You should also use an 'enum' struct...

  • Jez.L -

Une station de m?tro, c’est l’endroit o? le m?tro s’arrete.
Une station d’autobus, c’est l’endroit o? le bus s’arrete…
Devant moi, j’ai une station de travail :slight_smile:

----- Original Message -----
From: lloyd.dupont@wanadoo.fr (Lloyd Dupont)
To:
Sent: Tuesday, June 19, 2001 4:58 PM
Subject: [SDL] endianity

I have had binary compatibility for files on Windows, Solaris and AIX
before.
We had a system that converted everything to little endian format and
then dump the raw bytes to disk.

You need two functions for each data type ( I used C++ so they were
overloaded ):
ConvertToLittleEndian
ConvertFromLittleEndian
On a little endian computer they do nothing. On a big endian computer
they swap the bytes appropriately.

I can’t remember whether I used the endian swap on double and floats or
not. I will look into that and get back to you. The important thing
though is aside from endian issues they all had the same byte format.

I used
gcc on Solaris,
xlc on AIX,
and VisualC on Windows.

Unfortunately I never tried Linux.

Julien GUEDON wrote:>

----- Original Message -----
From: Lloyd Dupont <Lloyd.Dupont at wanadoo.fr>
To:
Sent: Tuesday, June 19, 2001 4:58 PM
Subject: [SDL] endianity

i wonder about endianity issue with double/float…
is it a stupid question ?

i have no idea of how they are laid in memory and write on disk.
could someone tell me ?

Just let me add an answer. I used to work on 3D graphic file formats imports
from Amiga, Mac and other big endian workstations.
I hope the following will help you :

the IEEE floats are 4bytes wide using this way ( I may be wrong )
1     digit for the sign
8     for the exponent part
23   for the value corps                        ( Oups, my english level

is decreasing … )

In fact, THEY ARE ALLWAYS STORED AS DONE FOR A DWORD. but THEY ALWAYS

FOLLOW IEEE SPECS.

That means you need to reverse datas in memory more or less this way :

void    bigToLittle(float* value)                /* could be called

‘littleToBig’ too … :slight_smile: /
{
unsigned char tmp;
unsigned char
ptr;

    ptr = (char*)(void*)value;

    /* Now me can switch the datas */
    tmp       = ptr[0];
    ptr[0]    = ptr[3];
    ptr[3]    = tmp;
    tmp       = ptr[1];
    ptr[1]    = ptr[2];
    ptr[2]    = tmp;

    /* absolutely not optimized .......... */
    /* never mind ... ;-) */

}

You should also use an 'enum' struct...

  • Jez.L -

Une station de m?tro, c’est l’endroit o? le m?tro s’arrete.
Une station d’autobus, c’est l’endroit o? le bus s’arrete…
Devant moi, j’ai une station de travail :slight_smile:

Adam wrote :

You need two functions for each data type ( I used C++ so they were
overloaded ):
ConvertToLittleEndian
ConvertFromLittleEndian
On a little endian computer they do nothing. On a big endian computer
they swap the bytes appropriately.

Could also use #define specs with on a C compiler.

I can’t remember whether I used the endian swap on double and floats or
not. I will look into that and get back to you. The important thing
though is aside from endian issues they all had the same byte format.

You also have to swap double and floats the same way, regarding their
respective sizes ( 4 and 8 bytes wide ).

NB : Lloyd Dupont and I think this mailing list is not the proper place to
have a technical talk about endianity. ( Am I wrong Lloyd ? ) If other
mailers keep interesting, we’ll keep writing here. Otherwise, if anyone has
a good sample or code or tip not using SDL it could be send directly to
Lloyd (Lloyd.Dupont at wanadoo.fr)
or to me (@Julien_Guedon).

Thank you for your answer Adam.

my main interest is in double/float.
as for other integer type there is SDL function which do the swap.

it seems that a (float *) can treated like an (int *) in purpose of
saving data and swaping them with SDL_Swap… function
but what about double ?

and thanks for your numerous answer to this little of topic subject.

Listen people, we’ve had the discussion about floats in files and network
protocols before on this list so I suggest you read the archives

To summarise:
If you want to transmit floats (via files or networks), keep in mind that

a) the byte-orders differ
b) the formats differ — this is mostly a historical thing since most modern
machines use IEEE-754 formats but there’s no guarantee that some exotic
device will surface again, most likely where you least expect it
c) the semantics differ

For practical purposes, c) is the biggie here. Once you’ve transmitted a
bunch of numbers, you want them to be interpreted the same way and operations
done on them to give the same results, and IEEE-[78]54 nonwithstanding,
there’s no guarantee for this. (Sometimes you can even get different results
when running the same binary on the same architecture - think FSIN on
an AMD vs an Intel x86)

So, lessons:

  1. Unless you know what you are doing, don’t transmit/store floats to other
    platforms. Use integers (fixnums if you need)
  2. also unless you know what you are doing, store/transmit floats in ASCII
    (text file formats are usually a good idea anyway)