Kod Graya, zwany też kodem cyklicznym, jest kodem, którego dwie kolejne wartości różnią się dokładnie jednym bitem. Wykorzystuje się go do wykrywania błędów komunikacji jak również systemach telewizji. W tym artykule zostanie opisane jak go obliczyć i zaimplementować do programu.
Poniższa tabelka przedstawia pierwsze 8 wartości kodu Graya i odpowiadającym im wartościom zapisanych dziesiętnie oraz binarnie:
Dziesiętnie | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
Binarnie | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 |
Kod Gray | 000 | 001 | 011 | 010 | 110 | 111 | 101 | 100 |
Jak można zauważyć jeśli weźmiemy 2n pierwszych wyrazów kodu Graya to są one pewną permutacją pierwszych 2n liczb naturalnych. Zgodnie z tym co zostało wcześniej wspomniane dwa kolejne wyrazy kodu Graya różnią się dokładnie jednym bitem.
Kod Graya można bardzo łatwo wyznaczyć pamiętając jedynie dwa pierwsze wyrazy, który mi zawsze są 0 i 1. W tym celu należy najpierw dołączyć do tabeli drugą, identyczną, ale odwracają kolejność wierszy. W pierwszej połowie tabeli należy dopisać 0, a w drugiej na początku 1. Przykładowo chcąc rozwinąć dwa pierwsze wyrazy:
Kod |
---|
0 0 |
0 1 |
1 1 |
1 0 |
Rozwijając dalej otrzymujemy:
Kod |
---|
0 00 |
0 01 |
0 11 |
0 10 |
1 10 |
1 11 |
1 01 |
1 00 |
Nie jest to jednak najbardziej efektywna metoda w celu otrzymania n-tego wyrazu. Istnieje prostszy wzór, który na polega na wykonaniu operacji XOR na liczbie n i liczbie n przesuniętej o jeden bit w prawo (ucinamy ostatni bit i dołączamy 0 z przodu). Przykładowo mając liczbę 5 należy przeliczyć ją na kod binarny: n = 1012 i obliczyć XOR(101, 010) = 111
Przeliczanie z kodu Graya na dziesiętny wymaga powtarzania dwóch operacji: XOR oraz przesunięcia w prawo. Początkowo maska jest ustalana na zapis kodu. Następnie dopóki wartość ta nie osiągnie 0 należy kolejno: przesunąć maskę w prawo o jedną pozycją, a następnie wykonać operację XOR(aktualny_kod, maska). Na koniec zostaje otrzymana wartość, która oznacza, który to jest kod z kolei.
Przykładowo biorąc kod 101 należy za maskę przyjąć początkowo 1101 i kolejno wykonywać następujące kroki:
#Wartość#Maska#Wynik11010110101110110011100010000001100110010000-
Maska osiągnęła wartość 0, więc wykonywanie zostaje przerwane. W wyniku została uzyskana wartość 10012 = 9. Można to szybko sprawdzić pamiętając wzór na n-ty wyraz kodu Graya. Otóż XOR(1001, 0101) = 1101. Sprawdzenie potwierdza poprawność obliczeń.
Poniższa funkcja generujKodGraya() generuje pierwsze 2n wartości kodu Graya. Przyjmuje ona tylko jeden argument n, który powinna być liczba całkowita większa od 0. W wyniku otrzymuje się tablicę wartości kodu Graya.
W celu wygenerowania wartości potrzebne są dwie pętle. Pierwsz określa ile jest już elementów w tablicy: 2, 4, 8, 16,.. Zagnieżdżona pętla FOR ma za zadanie skopiować aktulną tablicę i ją odwrócić. Dodanie bita 0 na początku nic nie zmienia, dlatego algorytm pomija ten krok. Jednak w celu dodania na początku bita 1 do kopiowanej wartości zostaje dodany aktualny rozmiar tablicy. Można tak zrobić, ponieważ mając 8 elementów w tablicy wszystkie mają ustawione 3 bity, a więc dodanie wartości 8 = 10002 dołączy na ich początek bit 1.
Przeliczanie liczby dziesiętnej na kod Graya to dosłownie jedna linijka:
Z kolei przeliczanie w drugą stronę wymaga zastosowanie pętli i wcześniech użytych operacji:
Poniższy fragment kodu wczytuje od użytkownika liczbę n, a następnie wypisuje 2n pierwszych wartości kodu Graya, ale przeliczone z zapisu binarnego na dziesiętny.