# Code de Gray

Le code de Gray, également appelé code Gray, code de Gros-Gray, ou code binaire réfléchi, est un type de codage binaire permettant de ne modifier qu'un seul bit à la fois quand un nombre est augmenté d'une unité. Cette propriété est importante pour plusieurs applications.
Le code porte les noms d'Agathon-Louis Gros qui publia un article sur le sujet en 1872$^,$$^,$ et de l'ingénieur américain Frank Gray qui déposa un brevet sur ce code en 1947.

## Principe et exemple

Le code de Gray est un codage binaire, c'est-à-dire une fonction qui associe à chaque nombre une représentation binaire. Cette méthode est différente du codage binaire naturel. Le tableau suivant montre partiellement le codage sur 4 bits (seules les 8 premières valeurs sont présentées, les huit suivantes avec le premier bit à 1 n'y sont pas).
| Codage décimal | Codage binaire naturel | Codage Gray ou binaire réfléchi |
| 0 | 0000 | 0000 |
| 1 | 0001 | 0001 |
| 2 | 0010 | 0011 |
| 3 | 0011 | 0010 |
| 4 | 0100 | 0110 |
| 5 | 0101 | 0111 |
| 6 | 0110 | 0101 |
| 7 | 0111 | 0100 |
La différence principale entre les deux est le fait que le codage de Gray de deux nombres consécutifs ne diffère que d'une position. Par exemple 5 est codé par 0111, et 6 est codé par 0101 : ici seul le deuxième bit change.

## Construction de la table par symétrie

Le nom de code binaire réfléchi, comme autre nom du code de Gray, vient d'une méthode de construction basée sur la réflexion de blocs de codes déjà construits :
* on choisit un code de départ : zéro est codé 0 et un est codé 1,
* puis, à chaque fois qu'on a besoin d'un bit supplémentaire, on symétrise la liste des codes déjà obtenus (comme une réflexion dans un miroir),
* enfin, on rajoute un 0 puis un 1 au début (à gauche) de chacun des codes. On a ainsi doublé le nombre de codes formés.
Exemple :

## Méthodes d'incrémentation

Il existe plusieurs méthodes pour incrémenter un nombre écrit selon le code de Gray (c'est-à-dire lui ajouter 1).

### Inverser pour obtenir un nouveau nombre

Pour passer d'une ligne à la suivante, on inverse le bit le plus à droite possible conduisant à un nombre nouveau. Cette méthode présente l'inconvénient de devoir connaître tous les codes de Gray qui précèdent.

### Selon la parité

Une autre méthode de calcul permettant de passer d'un nombre de Gray au suivant, et qui présente l'avantage de ne pas nécessiter de connaître l'ensemble des nombres précédents est la suivante :
* si le nombre de 1 est pair, il faut inverser le dernier chiffre.
* si le nombre de 1 est impair, il faut inverser le chiffre situé à gauche du 1 le plus à droite.
Exemple d'incrément basé sur la parité :
| 44 (pair) | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 27 (impair) | 0 | 1 | 0 | 1 | 1 | 0 |
| dernier chiffre | | | | | | | • | chiffre avant le dernier 1 | | | | • | ← | . |
| 44 → 45 | 0 | 1 | 1 | 1 | 0 | 1 | 1 | 27 → 28 | 0 | 1 | 0 | 0 | 1 | 0 |

## Calcul de moitié et double

Une méthode de calcul de la moitié d'un nombre pair consiste à éliminer le dernier chiffre et donc décaler les autres chiffres d'une position à droite.
Exemple de calcul de la moitié :
| 44 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 22 | 0 | 1 | 1 | 1 | 0 | 1 |
| 44 → 22 | | 0 | 1 | 1 | 1 | 0 | 1 | 22 → 11 | | 0 | 1 | 1 | 1 | 0 |
Une méthode de calcul du double d'un nombre consiste à insérer un chiffre supplémentaire à droite et donc décaler les autres chiffres d'une position à gauche.
* si le nombre de chiffres 1 est pair, le nombre est pair, il faut insérer un zéro à droite
* si le nombre de chiffres 1 est impair, le nombre est impair, il faut insérer le chiffre 1 à droite
Exemple de calcul du double :
| 22 (pair) | | 0 | 1 | 1 | 1 | 0 | 1 | 11 (impair) | | 0 | 1 | 1 | 1 | 0 |
| 44 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 22 | 0 | 1 | 1 | 1 | 0 | 1 |

## Intérêt : Éviter des états transitoires

Le fait de modifier plusieurs bits lors d'une simple incrémentation peut mener, selon le circuit logique, à un état transitoire indésirable dû au fait que le chemin logique de chaque bit dispose d'un délai différent. Ainsi, lors du passage de la valeur "01" à la valeur "10" en binaire naturel, il est possible d'observer un état transitoire "00" si le bit de droite commute en premier ou "11" dans le cas contraire. Si le circuit dépendant de cette donnée n'est pas synchrone, l'état transitoire peut perturber les opérations en faisant croire au système qu'il est passé par un état normalement non atteint à ce stade. Cela apparait pour les capteurs de positions, par exemple sur des règles optiques. Ce code permet de contourner cet aléa en forçant la commutation d'un seul bit à la fois, évitant ainsi les états transitoires.
Intérêt du code de gray :
| | Transitions incertaines sans code de Gray | Transitions déterministes avec le code de Gray |
| Modèle théorique (en haut) Réalité physique (en bas) | | |
| | Sans code de gray deux transitions peuvent se produire au lieu d'une. Entre ces deux transition l'état intermédiaire est indéterminé et indéterminable. C'est par exemple le cas entre les transitions t1 et t2 ou entre t3 et t4. | Avec le code de gray deux transitions ne peuvent se produire au lieu d'une. Autour de t1, il n'y a pas de changement. t1 n'est pas une transition. La transition survient sur t2. Autour de t4, il n'y a pas de changement. t4 n'est pas une transition. La transition survient sur t3. |
Unicité des transitions :
| 1 : | 0 | | 0 | ⬌ | 1 | | 1 | ⬌ | 0 | | 0 | ⬌ | 1 | | 1 | ⬌ | 0 |
| 2 : | 0 | | 0 | | 0 | ⬌ | 1 | | 1 | | 1 | | 1 | ⬌ | 0 | | 0 |
| 3 : | 0 | ⬌ | 1 | | 1 | | 1 | | 1 | ⬌ | 0 | | 0 | | 0 | | 0 |

## Applications
### Roue codeuse

Le code de gray trouve une application pratique dans la roue codeuse. Dans l'illustration, on trouve huit états et huit transitions sans qu'il n'y ait ni maximum, ni minimum, du fait des symétries. Chaque huitième de tour n'occasionne qu'une unique transition. Ceci permet donc bien d'encoder un angle.
L'illustration montre la forme de la roue, la table montre les transitions entre états, le graphe montre la position les transitions sur la roue. Le code est implémenté en noir et blanc, pour explication, les transitions sont explicitées en rouge, vert et bleu.
Ces explications prennent comme références les directions d'une girouette (E=est, N=nord, O=ouest, S=sud).
| Transition | i | .... | e | .... | m | .... | e | .... | i | .... | e | .... | m | .... | e | .... | i | .... | e | .... | m |
| Cercle extérieur | Est | Est | | Nord | Nord | Nord | | Ouest | Ouest | Ouest | | Sud | Sud | Sud | | Est | Est | Est | | Nord | Nord |
| Cercle médian | Est | Est | Est | Est | N | Ouest | Ouest | Ouest | Ouest | Ouest | Ouest | Ouest | S | Est | Est | Est | Est | Est | Est | Est | N |
| Cercle intérieur | E | Nord | Nord | Nord | Nord | Nord | Nord | Nord | O | Sud | Sud | Sud | Sud | Sud | Sud | Sud | E | Nord | Nord | Nord | Nord | Nord | Nord | Nord |
| Transition | i | .... | e | .... | m | .... | e | .... | i | .... | e | .... | m | .... | e | .... | i | .... | e | .... | m |

### Souris

Le décodage des signaux lumineux d'un axe de souris mécanique est un décodage de code de Gray à 2 bits (décodage différentiel dans ce cas, car ce que l'on veut obtenir n'est pas la valeur décodée mais les transitions ±1 mod 4 de la valeur décodée).

### Tables de Karnaugh

Le code Gray sert également dans les tables de Karnaugh utilisées lors de la conception de circuits logiques.

### Code Baudot

Le principe du code de Gray se retrouve dans le code Baudot, dans lequel les voyelles et les consonnes sont classées dans leur ordre alphabétique, et un seul bit change entre deux lettres successives.
Otto Schäffler aurait également eu un télégraphe similaire.

## Transcodage binaire
### Transcodage binaire / Gray

En notant $b=b_{0}b_{1}...b_{k}$ un entier écrit en binaire (où $b_{0}$ est le bit de poids fort), et de même en notant $g=g_{0}g_{1}...g_{k}$ le code de Gray correspondant, il est possible de montrer (par exemple en utilisant les tables de Karnaugh), que $g_{i}=b_{i}\oplus b_{i-1}$ (où $\oplus$ désigne la fonction OU exclusif) ; autrement dit, pour obtenir $g$, il suffit d'effectuer un OU exclusif entre $b$ et ce même nombre $b$ décalé d'un bit vers la droite (c'est-à-dire, en binaire, divisé par 2), ce qu'exprime la fonction suivante écrite en langage C :
Algorithme de codage d'un nombre b en code de Gray :
Par exemple, le nombre décimal 7 s'écrit 0111 en base 2. Son code de Gray s'obtient comme suit :
7 est représenté par 0100 en code de Gray.
Algorithme de décodage rapide pour des mots de 64 bits (pour des mots de 32 bits, remplacer 32 par 16) :

### Transcodage Gray / binaire

En notant $b=b_{0}b_{1}...b_{k}$ un entier écrit en binaire (où $b_{0}$ est le bit de poids fort), et de même en notant $g=g_{0}g_{1}...g_{k}$ le code de Gray correspondant, selon ce qui précède, on détermine facilement le nombre binaire d'un code de Gray donné : $b_{i}=g_{0}\oplus g_{1}\oplus g_{2}\oplus ...\oplus g_{i}$ (où $\oplus$ désigne la fonction OU exclusif). On a donc :
$b_{0}=g_{0}$
$b_{1}=g_{0}\oplus g_{1}$
$b_{2}=g_{0}\oplus g_{1}\oplus g_{2}$
$b_{3}=g_{0}\oplus g_{1}\oplus g_{2}\oplus g_{3}$
etc.
Donc pour obtenir le code binaire d'un code de Gray donné, on passe de gauche (poids fort) à droite (poids faible). Le bit de poids fort est le même en binaire que dans le code de Gray $b_{0}=g_{0}$. Le bit binaire suivant reste le même si le bit de Gray suivant vaut zéro et change si le bit de Gray suivant vaut 1. On répète cela pour tous les bits, jusqu'au bit de poids le plus faible.

## Historique

L'ingénieur américain Frank Gray déposa un brevet sur ce code en 1947, mais le code est plus ancien ; il a notamment été utilisé dans le code Baudot.
Luc-Agathon-Louis Gros, qui fut clerc de notaire puis conseiller à la Cour d'appel de Lyon, publia en 1872 un opuscule, Théorie du baguenodier par un clerc de notaire lyonnais, où ce code était présenté pour la première fois en lien avec un casse-tête, le jeu du baguenaudier.
Cette séquence a été notamment vulgarisée dans le jeu du baguenaudier (jeu qui nous a été transmis par Jérôme Cardan et qui a été résolu par John Wallis).
Jeu du baguenaudier :
| Case 1 : | 1 | | 1 | 0 | | 0 | 1 | | 1 | 0 | | 0 | 1 | | 1 | 0 |
| Case 2 : | 1 | ⬌ | 0 | 0 | | 0 | 0 | ⬌ | 1 | 1 | | 1 | 1 | ⬌ | 0 | 0 |
| Case 3 : | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | ⬌ | 0 | 0 | | 0 | 0 |
| Case 4 : | 1 | | 1 | 1 | ⬌ | 0 | 0 | | 0 | 0 | | 0 | 0 | | 0 | 0 |