One little, two little, three little endians…
December 24, 2006 on 12:58 pm | In Programing |Víte co mají společného čísla -2030043136 a 135? Taky jsem nevěděl, přišel jsem na to až po více než 40 minutách.
Jsou to totiž v podstatě stejná čísla
Jen je u nich zaměněno pořadí bytů v paměti. O co jde? Paměť PC je rozdělena na jednotky. Tyto adresovatelné jednotky se nazývají byty [čti bajty]. 1 byte má 8 bitů [čti bitů] - z toho tedy vyplývá, že maximalní hodnota, která se dá na jedno místo uložit je 255. My samozdřejmě potřebujeme pracovat s většími celky než 1 byte a proto se díváme na více za sebou jdoucích bytů jako na jednu spojitou část. No a právě zde je kámen úrazu. Čísla, o kterých jsem se zmínil na začátku, jsou uložena do čtyř bytů, tedy do 4 po sobě jdoucích jednotek. Jenže ony jsou dva způsoby jak toto více bytové číslo uložit. V tabulce je vyobrazeno číslo 135 převedené do dvojkové soustavy a rozepsané do jednotlivých paměťových buněk.
| adresa | big endian | little endian |
|---|---|---|
| 5678 | 00000000 | 10000111 |
| 5679 | 00000000 | 00000000 |
| 567A | 00000000 | 00000000 |
| 567B | 10000111 | 00000000 |
Big endian
Je způsob, kdy se na nižší adresu dávají vyšší řády čísla. Používá se třeba na procesorech od Motoroly.
Little endian
Je přesně opačný - na nižší adresy se dávají nižší řády čísla, tento způsob používají nám dobře známe intelácke procesory a samodřejmě i AMDčka.
Na tyto dva odlišné způsoby je potřeba dávat si pozor právě u síťové komunikace, protože tady si nemůžete být jistí, co je na druhé straně za mašinu. Třeba komunikace mezi jednotlivými účastníky sítě bittorrent posílá data jako big-endian a to i přesto, že většina počítačů, na kterých klienti běží používají little-endian!
Převodník
Vytvořit fci, která data převede big-endian na little-endian a opačně je jednoduché:
void preved_endian(unsigned char *source, unsigned char *destination, int size)
{
// Counter
int x;
// Reverse all the bytes
for(x = 0; x < size; x++)
destination[x] = source[size - x - 1];
}
Potřebujete-li tedy přehodit třeba integer, tak stačí zavolat preved_endian(&zdroj, &cil, sizeof(int)); No možná by ještě pro umlčení compileru bylo dobré ukazatele přetypovat - (unsigned char *) &zdroj.
3 Comments »
RSS feed for comments on this post. TrackBack URI
Leave a comment
Powered by WordPress with Pool theme design by Borja Fernandez.
Entries and comments feeds.
Valid XHTML and CSS. ^Top^
Pozor, ta funkce ti převrátí bity a ne byty.
Comment by Ondřej Garncarz — 2006-12-25 #
To neni pravda. Podivej se na tu tabulku - poradi bitu v bytu je stale stejne! Pouze prevrati ulozeni jednotlivych bytu v dane casti pameti.
Comment by jarcec — 2006-12-25 #
Jej, pardon, jsem vnímal “source” jako pole bitů.
Comment by Ondřej Garncarz — 2006-12-25 #