Code de Gray sans nuances

ccgousset Messages postés 150 Date d'inscription samedi 1 août 2009 Statut Membre Dernière intervention 4 mars 2023 - 27 oct. 2016 à 14:09
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 - 25 nov. 2016 à 10:43
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/101684-code-de-gray-sans-nuances

cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
25 nov. 2016 à 10:43
Je vais simplement la réactiver pour que tu puisses y apporter des modifications.
ccgousset Messages postés 150 Date d'inscription samedi 1 août 2009 Statut Membre Dernière intervention 4 mars 2023
Modifié par ccgousset le 24/11/2016 à 23:40
Bonjour Pingu , que dois je faire le source est annulé bien sur. Je dois remettre un bon code ou un patch avec les votres ? Merci
ccgousset Messages postés 150 Date d'inscription samedi 1 août 2009 Statut Membre Dernière intervention 4 mars 2023
24 nov. 2016 à 10:33
je le fais sous deux jours merci de la correction
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
Modifié par cptpingu le 31/10/2016 à 10:51
Message "admin", à supprimer:

Bonjour ccgousset. Peux-tu mettre à jour ta source au plus vite ? Ça fait déjà quelques jours qu'une source érronée fait la "une" de la section C++. Ça ne fait pas très sérieux pour CodeS-SourceS. Je serais malheureusement obligé de la désactiver d'ici 24h si aucune correction n'est apportée.

Merci de ta compréhension.
pgl10 Messages postés 381 Date d'inscription samedi 18 décembre 2004 Statut Non membre Dernière intervention 25 avril 2024 11
29 oct. 2016 à 21:50
Bonjour,

En plus, je vous propose aussi la fonction inverse :

uint64_t gray_to_bin(uint64_t k)
{
  uint64_t d, n = k, b = 1;
  do {
    d = n >> b;
    n = n ^ d;
    b = b << 1;    
  } while(d > 1);
  return n;
}

Bien à vous !
pgl10 Messages postés 381 Date d'inscription samedi 18 décembre 2004 Statut Non membre Dernière intervention 25 avril 2024 11
29 oct. 2016 à 19:38
Bonjour tous,

Merci ccgousset et cptpingu.

Pour tous ceux qui ont des petits ennuis avec l'affichage des caractères accentués en mode console sous Windows, je rappelle ici qu'il suffit d'ajouter le code suivant :

#include <windows.h>
#include <string>
std::string print(const std::string tab)
{
    char* buf = new char[1+tab.size()];
    CharToOemA(tab.c_str(), buf);
    std::string str(buf);
    delete [] buf;
    return str;
}

et de remplacer ensuite, par exemple, l'instruction :

  std::cout << "Génération du code de Gray, nombre de rang: ";

par celle-ci :

  std::cout << print("Génération du code de Gray, nombre de rang: ");

Cela fonctionne aussi pour afficher un char[] ou un std::string

Salutations
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
Modifié par cptpingu le 27/10/2016 à 18:11
Bonjour.

Plusieurs soucis avec ce code:
  • Tout d'abord, le plus gênant: il ne fait pas ce qu'il dit faire :(. Ici, n'est pas calculé un code de gray, mais un simple nombre binaire. Le code de Gray doit respecter un certain ordre. Par exemple au rang 7, ce n'est pas 111 mais 100
  • Using namespace a éviter, voir: http://0217021.free.fr/portfolio/axel.berardino/articles/bon-usage-using-namespace
  • Les *.exe, *.layout, *.depend, *.cbp et tous les fichiers temporaires ne sont pas nécessaires.
  • Attention de bien compiler avec tous les warnings d'affichés. Tu as par exemple ta variable "p" qui n'était pas utilisé.
  • Concaténer des std::string c'est particulièrement inefficace. Mieux vaut utiliser un std::ostringstream qui permet des concaténations rapides. De toute façon, ici, il n'est nullement besoin de passer par une représentation de "chaînes". On peut tout faire avec des nombres, ce qui est beaucoup beaucoup plus performant !
  • Peu d'explications sur ce que fait le code, ce qu'est un code de Gray, à quoi ça sert, etc...
  • Pas de commentaires "utiles", voir: http://0217021.free.fr/portfolio/axel.berardino/articles/ecrire-de-bons-commentaires
  • Plutôt que d'écrire sur la sortie standard, mieux vaut écrire dans un flux. Ce qui laisse à l'utilisateur de la fonction le choix de la sortie.



Afin d'illustrer tous ces points, voici comment une source "propre" devraît être postée (description, commentaires et code):

Description:

Le code de Gray, également appelé 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é. Ce code (Code de Gray) est surtout utilisé pour des capteurs de positions, par exemple sur des règles optiques. En effet, si on utilise le code binaire standard, lors du passage de la position un (01) à deux (10), permutation simultanée de 2 bits, il y a un risque de passage transitoire par trois (11) ou zéro (00), ce qu'évite le code de Gray.

Plus d'info ici: https://fr.wikipedia.org/wiki/Code_de_Gray


Code:
#include <iostream>
#include <stdint.h>

/*!
** Convert a decimal number into its binary representation
**
** @param k The decimal number
** @return A binary representation
*/
uint64_t int_to_bin(uint64_t k)
{
    if (k == 0)
      return 0;

    if (k == 1)
      return 1;

    return (k % 2) + 10 * int_to_bin(k / 2);
}

/*!
** Convert a binary number into a gray binary number.
**
** @param k The binary number
** @return A gray binary number
**
** @note La méthode la plus simple consiste à calculer le OU exclusif entre
**       le binaire de départ et ce même binaire décalé d'un rang à droite.
** @example Soit le nombre 7:
**       7 s'écrit 0111 en base 2.
**           0111 (7)
**         ^ 0011 (7 >> 1)
**         ------
**           0100 (Nombre de gray numéro 7)
*/
uint64_t bin_to_gray(uint64_t k)
{
  return k ^ (k >> 1);
}

/*!
** Generate a table with dec, bin and gray code into a stream.
**
** @param step Number of items in the table
** @param out Where to output result
*/
void generate_gray_code(uint64_t step, std::ostream& out)
{
  out << "DEC  \t|\tBIN\t|\tGRAY\n"
      << "---------------------------------------\n";
  for (uint64_t i = 0; i < step; ++i)
    out << i << ":\t" << "|\t" << int_to_bin(i) << "\t|\t" << int_to_bin(bin_to_gray(i)) << "\n";
}

int main()
{
  const uint64_t MAX = 2 << 19; // 2^20

  uint64_t nb = 0;
  std::cout << "Génération du code de Gray, nombre de rang: ";
  std::cin >> nb;
  if (nb > MAX)
  {
    // Pour une taille plus grande, voir du côté de GMP
    std::cout << "Le nombre donné dépasse le rang maximal " << MAX << ", soit une taille de 20" << std::endl;
    return 1;
  }
  generate_gray_code(nb, std::cout); // std::cout peut être remplacé par un fichier, un socket, etc...

  return 0;
}
Rejoignez-nous