Prohození hodnot XORem

Technology
12 hours ago
8
4
2
Avatar
Author
Albert Flores

půlslabik bez pomocné proměnné pomocí XORu Prohození hodnot XORem je v programování jedním z algoritmů, kterými lze dosáhnout prohození hodnot dvou proměnných bez použití pomocné dočasné proměnné. Používá k tomu bitovou operaci úplné disjunkce.

Algoritmus

Algoritmus se skládá ze tří kroků, přičemž všechny využívají operaci XOR:

X := X xor Y Y := Y xor X X := X xor Y

Jednotlivé řádky obvykle přímo odpovídají instrukcím jazyka symbolických adres respektive přímo strojovým instrukcím. Následující příklad uvádí instrukce na platformách IBM System/370 a x86:

PseudokódIBM System/370x86

Pro funkčnost algoritmu je zásadní, aby jeho vstupem nebylo dvakrát stejné umístění. Protože totiž pro každé x je výsledek operace x XOR x nulový, bylo by hned v prvním kroku toto umístění vynulováno a tím jeho hodnota ztracena.

Důkaz správnosti

Správnost algoritmu je odvozena z toho, že binární operace XOR (značená \oplus) na bitových řetězcích pevné délky splňuje následující čtyři vlastnosti: * L1. Komutativitu: A \oplus B = B \oplus A * L2. +more Asociativitu: (A \oplus B) \oplus C = A \oplus (B \oplus C) * L3. Existenci neutrálního prvku: existuje prvek, značený 0, pro který platí A \oplus 0 = A pro každé A * L4. Každý prvek je sám sobě inverzním: pro každé A, A \oplus A = 0.

KrokOperaceRegistr 1Registr 2Redukce dle vlastnosti
0Úvodní hodnotaAB-
1R1 := R1 XOR R2A \oplus B\ B-
2R2 := R1 XOR R2A \oplus B(A \oplus B) \oplus B = A \oplus (B \oplus B) = A \oplus 0 =AL2 L4 L3
3R1 := R1 XOR R2(A \oplus B) \oplus A = A \oplus (A \oplus B) = (A \oplus A) \oplus B = 0 \oplus B = B \oplus 0 = B\ AL1 L2 L4 L1 L3

Varianty

Podobný algoritmus lze realizovat pomocí sčítání a odčítání:

void addSwap (unsigned int *x, unsigned int *y) { if (x != y) { *x = *x + *y; *y = *x - *y; *x = *x - *y; } }

Jeho správnost je ale závislá na tom, že nedojde k celočíselnému přetečení. Je-li například práce na celých číslech realizována s podporou libovolné přesnosti nebo v rámci modulární aritmetiky, algoritmus funguje. +more Například v rámci jazyka C tento algoritmus funguje, neboť sčítání a odčítání dle standardu odpovídá operacím v cyklické grupě \mathbb Z/2^s\mathbb Z, kde s je počet bitů.

Vzhledem k dodatečnému požadavku na vlastnosti sčítání je tato varianta používána ještě méně než varianta základní.

Výhody a nevýhody

Nevýhody: * Je-li v daném kontextu dost volných registrů procesoru, pak bude prohození hodnot pomocí nějakého volného pravděpodobně rychlejší * Moderní počítačové architektury často využívají překrývané zpracování strojových instrukcí. To umí rychle zpracovávat kód, ve kterém zpracování instrukce nezávisí na výsledku instrukcí těsně předcházejících. +more V tomto algoritmu na sebe všechny tři instrukce bezprostředně navazují, takže překrývané zpracování nemůže být využito a procesor je bude zpracovávat pomalu postupně. * Pro programátora, který postup nezná, se jedná o obtížně pochopitelný trik, jehož prokouknutí ho při studování kódu zbytečně zdrží.

Výhody: * Instrukce XOR má na některých architekturách úsporné kódování (tedy využití algoritmu může šetřit instrukční cache) * V rámci části kódu náročné na volné registry může mít ušetření pomocného registru zásadní dopady na výkon. * Na jednočipových počítačích a jiných malých platformách může mít smysl i ušetření pomocné operační paměti

5 min read
Share this post:
Like it 8

Leave a Comment

Please, enter your name.
Please, provide a valid email address.
Please, enter your comment.
Enjoy this post? Join Cesko.wiki
Don’t forget to share it
Top