Partage
  • Partager sur Facebook
  • Partager sur Twitter

Algorithme de conversion de binaire vers base 10.

Je sais, on va m'engueuler mais j'ai pas trouvé ...

Sujet résolu
    19 décembre 2009 à 13:02:51

    Bonjour !

    Dans le besoin d'un convertisseur rapide de binaire vers décimal, je me tourne vers vous : comment convertir un nombre binaire en nombre décimal par le biais d'un programme ?
    J'ai cherché sur le forum et sur le Web mais les seules choses que j'ai trouvé c'est des conversions de décimal vers binaire ou des conversions qui ne marchent pas.
    Quelle est la formule ?

    PS : voilà le début du code ...
    int i = 10; // i = 2 en mode non-binaire

    Merci ! ;)
    • Partager sur Facebook
    • Partager sur Twitter
      19 décembre 2009 à 13:09:34

      salut, c'est au programme de 1er donc voila
      2 solution ->

      1) tu code chaque chiffre comme une valeur hexa et tu les met a la chaine
      2) tu prend un tableau des valeur binaire ronde (1, 2, 4, 8, 16 ...) et tu addition les valeur a 1
      par exemple pour 0101 sa fait 0*8 + 1*4 + 0*2 + 1*1 donc 5

      ... j'explique trop mal o_O
      • Partager sur Facebook
      • Partager sur Twitter
        19 décembre 2009 à 13:12:12

        C'est pas très classe ce que tu nous fais... un int, c'est un nombre qui a une valeur, quelle que soit sa base... La, ton int vaut 10, 0xA, tout ce que tu veux mais certainement pas 2. Tu veux peut-être faire ça au niveau de chaines de caractère. Dans ce cas, c'est simple.
        std::string a("1001");
        int value = 0;
        for(int i = a.length() - 1; i > -1 ; i--)
        {
             value += pow(i, 2) * ((a[i] == '1') ? 1 : 0);
        }
        

        Je ne sais pas si c'est correct mais c'est ce qui me vient en tête...
        • Partager sur Facebook
        • Partager sur Twitter
          19 décembre 2009 à 13:15:19

          1001101 (base 2)

          1*2^6 + 0*2^5 + 0*2^4 + 1*2^3 + 1*2^2 + 0*2^1 + 1*2^0
          = 64 + 0 + 0 + 8 + 4 + 0 + 1
          = 77 (base 10)
          • Partager sur Facebook
          • Partager sur Twitter
            19 décembre 2009 à 13:21:52

            gan_> Ok, c'est bien pour convertir dec vers bin mais après pour l'inverse ...

            Naj> Donc ce code :
            #include <iostream>
            #include <cmath>
            
            int main(int argc, char * argv[])
            {
            std::string s("10");
            std::string finally("");
            int val = 0;
            
            for(unsigned int ui = 0; ui < s.size(); ui++)
            {
            val = pow(ui, 2) * ((s[ui] == '1') ? 1 : 0);
            finally += val;
            }
            
            std::cout << finally << std::endl;
            std::cin.ignore();
            }
            

            Afficherait bien la chaîne 2 ?

            EDIT : converting to int from double.

            Chlab_lak> Ah ok. Je test aussi ;)
            • Partager sur Facebook
            • Partager sur Twitter
              19 décembre 2009 à 13:31:39

              Citation : Shydow

              gan_> Ok, c'est bien pour convertir dec vers bin mais après pour l'inverse ...


              o_O
              j'explique pour aller du bien vers dec (même méthode que Chlab_lak)
              • Partager sur Facebook
              • Partager sur Twitter
                19 décembre 2009 à 13:39:26

                gan_> Ok, mais tu as édité ton message pendant que je postais ^^"
                • Partager sur Facebook
                • Partager sur Twitter
                  19 décembre 2009 à 13:47:21

                  Il faut que tu comprenne que base 2 et base 10 ne sont que des représentations textuelles. Un nombre est quant à lui un nombre et il n'est au fond dans aucune base quand la machine le manipule -- il est juste au format compris par la machine. C'est tout.


                  Pour l'algo, il n'y a pas de secret..
                  - nombre vers chaine (quelle que soit la base) -> division successives.
                  - chaine (quelle que soit la base) vers nombre -> méthode de horner


                  PS: oubliez pow, cette approche n'est pas du tout efficace.

                  Bon je n'ai pas réussi a retrouver un seul endroit de la demi-douzaine où j'avais posté le code, donc le revoilà:
                  #include <string>
                  #include <iostream>
                  #include <stdexcept>
                  #include <vector>
                  #include <iterator>
                  
                  
                  template <typename E>
                  struct digits_trait {};
                  
                  template <> struct digits_trait<char> {
                      char operator[](char i) const {
                  	return "0123456789abcdefghijklmnopqrstuvwxyz"[i];
                      }
                  };
                  
                  template <> struct digits_trait<wchar_t> {
                      wchar_t operator[](char i) const {
                  	return L"0123456789abcdefghijklmnopqrstuvwxyz"[i];
                      }
                  };
                  
                  template <typename E, typename N>
                  std::basic_string<E> number2base(N n, int base) {
                      // const E digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
                      digits_trait<E> digits;
                      std::basic_string<E> result;
                      // result.reserve(operation_savante_à_base_de_logarithme(n));
                      while (n) {
                          N digit = n % base;
                          n /= base;
                          result += digits[digit];
                      }
                      return std::basic_string<E>(result.rbegin(), result.rend());
                  }
                  
                  int digitValue(char digit) {
                      if (digit >= 'a' && digit <='z') {
                  	return digit - 'a' + 10;
                      } else if (digit >= 'A' && digit <='Z') {
                  	return digit - 'A' + 10;
                      } else if (digit >= '0' && digit <='9') {
                  	return digit - '0';
                      } else {
                  	throw std::runtime_error("Invalid digit");
                      }
                  }
                  
                  unsigned long base2number(std::string const& str, int base)
                  {
                      unsigned long result = 0;
                      for (std::string::const_iterator b = str.begin(), e = str.end()
                  	    ; b != e
                  	    ; ++b
                  	)
                      {
                  	// std::cout << "r <- " << base << "*" << result << "+" << *b << "(" << digitValue(*b) << ")\n";
                  	result = base * result + digitValue(*b);
                      }
                      return result;
                  }
                  
                  typedef std::vector<unsigned char> DigitsVector;
                  DigitsVector toTab(unsigned int n, unsigned int base=10)
                  {
                      DigitsVector res;
                      // éventuellement res.reserve(opération savante à base de log_{base}(n));
                      do {
                         res . push_back(n%base);
                      } while (n /= base) ;
                      return DigitsVector(res.rbegin(), res.rend());
                  }
                  
                  
                  int main (int argc, char **argv)
                  {
                      int n;
                      // std::cout << base2number("ff", 16);
                      // return 0;
                      std::cout << "n :";
                      while (std::cin >> n) {
                  	const std::string v2 = number2base<char>(n,2);
                  	const std::string v8 = number2base<char>(n,8);
                  	const std::string v16 = number2base<char>(n,16);
                  	const DigitsVector  v = toTab(n);
                  	std::cout 
                  	    << "   -- 2: " << v2 << "(" << base2number(v2,2) << ")"
                  	    << "   -- 8: o" << v8 << "(" << base2number(v8,8) << ")"
                  	    << "   -- 16: 0x" << v16 << "(" << base2number(v16,16) << ")"
                  	    << "   -- ";
                  	std::copy(v.begin(),v.end(), std::ostream_iterator<int>(std::cout, " "));
                  	std::cout
                  	    << std::endl;
                      }
                  
                      return 0;
                  }
                  
                  • Partager sur Facebook
                  • Partager sur Twitter
                  C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
                    19 décembre 2009 à 13:54:17

                    ou tout simplement :
                    #include <iostream>
                    #include <cmath>
                    
                    int main(int argc, char * argv[])
                    {
                       std::string s("10");
                       int val = 0;
                       int i = 1;
                       for(unsigned int ui = 0; ui < s.size(); ui++)
                       {
                             val += (s[ui] == '1') * i;
                             i = i * 2;
                       }
                    }
                    
                    • Partager sur Facebook
                    • Partager sur Twitter
                      19 décembre 2009 à 13:56:30

                      gan_> ISO C++ forbids comparison between pointer and integer
                      '1' et pas "1"
                      • Partager sur Facebook
                      • Partager sur Twitter
                        19 décembre 2009 à 13:58:13

                        Citation : Shydow

                        gan_> ISO C++ forbids comparison between pointer and integer
                        '1' et pas "1"


                        exact ! :D
                        c'est l'habitude des QString :(

                        [edit] sinon, sa marche ?
                        • Partager sur Facebook
                        • Partager sur Twitter
                          19 décembre 2009 à 13:59:26

                          En plus
                          #include <iostream>
                          #include <cmath>
                          
                          int main(int argc, char * argv[])
                          {
                          std::string s("10");
                          int val = 0;
                          int i = 1;
                          
                             for(unsigned int ui = 0; ui < s.size(); ui++)
                             {
                                if (s[ui] == '1')
                                   val += 1 * i;
                                i = i * 2;
                             }
                             
                             std::cout << i;
                             std::cin.ignore();
                          }
                          // ton code avec le cout et la pause en plus
                          


                          Affiche 4 et pas 2 ^^"
                          • Partager sur Facebook
                          • Partager sur Twitter
                            19 décembre 2009 à 14:00:51

                            Citation : Shydow

                            En plus

                            #include <iostream>
                            #include <cmath>
                            
                            int main(int argc, char * argv[])
                            {
                            std::string s("10");
                            int val = 0;
                            int i = 1;
                            
                               for(unsigned int ui = 0; ui < s.size(); ui++)
                               {
                                  if (s[ui] == '1')
                                     val += 1 * i;
                                  i = i * 2;
                               }
                               
                               std::cout << i;
                               std::cin.ignore();
                            }
                            // ton code avec le cout et la pause en plus
                            



                            Affiche 4 et pas 2 ^^"



                            si tu n'affiche pas la bonne variable c'est normal :)
                            il faut prendre val en sortie, pas i :lol:
                            • Partager sur Facebook
                            • Partager sur Twitter
                              19 décembre 2009 à 14:09:37

                              Confusion de ma part ^^"

                              Il marche pas quand la chaine finit par 1 mais pas quand elle finit par zéro : dans ce cas, val est toujours égal à 1 ...
                              • Partager sur Facebook
                              • Partager sur Twitter
                                19 décembre 2009 à 14:26:56

                                normal, il faut prendre la chaine a l'envers
                                for(unsigned int ui = 0; ui < s.size(); ui++)
                                	{
                                		if (s[s.size() - ui - 1] == '1')
                                		{
                                			val = val + i;
                                		}
                                		i = i * 2;
                                	}
                                

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  19 décembre 2009 à 18:51:25

                                  Ou commencer le compte à l'envers ^^"
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    19 décembre 2009 à 19:07:23

                                    Là ça va (si on excepte que tout ce qui n'est pas '1' est traité comme un '0') parce que vous bossez sur des entiers, mais cette approche souffre de problèmes d'approximations avec des réels. D'où Horner...
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                    C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
                                      19 décembre 2009 à 21:03:39

                                      Je viens de jeter un coup d'oeil sur la méthode d'Horner, même si je n'ai pas tout compris, sa vitesse doit être effarante par rapport à un algorithme naïf, vu qu'elle n'a a calculer aucun carré sur une conversion d'une base à une autre !
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        19 décembre 2009 à 21:07:38

                                        Citation : Gigotdarnaud

                                        Je viens de jeter un coup d'oeil sur la méthode d'Horner, même si je n'ai pas tout compris, sa vitesse doit être effarante par rapport à un algorithme naïf, vu qu'elle n'a a calculer aucun carré sur une conversion d'une base à une autre !


                                        ma methode n'utilise aucun carré o_O
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          19 décembre 2009 à 22:38:26

                                          JE voudrais pas dire, mais il existe la fonction strtol dans la bibliothèque C...
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            20 décembre 2009 à 8:34:53

                                            Citation : QuentinC 2

                                            JE voudrais pas dire, mais il existe la fonction strtol dans la bibliothèque C...


                                            ...?
                                            On parle de binaire vers décimal pas de const char* vers long là o_O
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              20 décembre 2009 à 10:00:17

                                              Citation

                                              On parle de binaire vers décimal pas de const char* vers long là


                                              Ben oui, justement : strtol prend une chaîne représentant un nombre dans une base quelconque, donc tu peux convertir une chaîne représentant un nombre binaire.
                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                20 décembre 2009 à 10:29:10

                                                Pour passer d'une base 2 à une base 10, on peut faire ça :

                                                On stocke le nombre binaire dans un string.

                                                On lit chaque caractères de string.
                                                Pour chaque membre du vector, on multplie par 2.
                                                On rajoute 0 si le caractère est '0', sinon on rajoute 1 -> dans le vector

                                                On fait la somme de tous les éléments du vector
                                                Et on l'affiche.

                                                #include <iostream> // std::cout, std::cin
                                                #include <string> // std::string
                                                #include <vector> // std::vector
                                                #include <algorithm> // for_each()
                                                
                                                typedef unsigned long long int ulli; // Pour eviter des types super longs
                                                
                                                inline void foisDeux (ulli &nbr) {
                                                     nbr *= 2;
                                                }
                                                
                                                int main (void) {
                                                    std::vector <ulli> decimal(0,0);
                                                    std::string binaire;
                                                    ulli somme = 0; //Va contenir le nombre decimal (somme des elements du vector
                                                                    //"decimal")
                                                
                                                    std::cin >> binaire;
                                                
                                                    for (unsigned i = 0; i < binaire.length(); i++) {
                                                        for_each (decimal.begin(), decimal.end(), foisDeux);
                                                        decimal.push_back ( (ulli) (binaire[i] == '0') ? 0 : 1 );
                                                    }
                                                
                                                    for (unsigned i = 0; i < decimal.size(); i++)
                                                        somme += decimal[i];
                                                
                                                    std::cout << somme;
                                                
                                                    getchar();
                                                
                                                    return EXIT_SUCCESS;
                                                
                                                }
                                                
                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  20 décembre 2009 à 10:33:47

                                                  QuentinC 2> Ah ok ^^

                                                  Je cherchais surtout un algorithme mais c'est pas grave, j'ai trouvé les deux ^^

                                                  Algo-rythme> Je testerai également ;)

                                                  Merci à tous ! -résolu-
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    20 décembre 2009 à 13:26:56

                                                    Citation : Shydow

                                                    On parle de binaire vers décimal pas de const char* vers long là o_O


                                                    binaire, décimal, octal, hexadécimal, ... ne sont que des représentations textuelles de nombres.
                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                    C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
                                                      22 décembre 2009 à 21:22:06


                                                      Naj> Donc ce code :
                                                      #include <iostream>
                                                      #include <cmath>
                                                      
                                                      int main(int argc, char * argv[])
                                                      {
                                                      std::string s("10");
                                                      std::string finally("");
                                                      int val = 0;
                                                      
                                                      for(unsigned int ui = 0; ui < s.size(); ui++)
                                                      {
                                                      val = pow(ui, 2) * ((s[ui] == '1') ? 1 : 0);
                                                      finally += val;
                                                      }
                                                      
                                                      std::cout << finally << std::endl;
                                                      std::cin.ignore();
                                                      }
                                                      

                                                      Afficherait bien la chaîne 2 ?</citation>
                                                      Euh... Je pense même pas qu'il compilera... Ajouter un int à un string, c'est bizarre, non ?
                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        22 décembre 2009 à 21:33:24

                                                        Je suis pas expert en C++ mais vous ne vous compliquez pas un peu la vie là ? ^^

                                                        #include <iostream>
                                                        #include <string>
                                                        
                                                        int main(void) {
                                                        	std::string s("11001");
                                                        	int val = 0;
                                                        	
                                                        	for (int i = 0; i < s.size(); i++) {
                                                        		val <<= 1;
                                                        		val ^= (s[i] == '0') ? 0 : 1;
                                                        	}
                                                        	std::cout << val;
                                                        	return 0;
                                                        }
                                                        
                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                          22 décembre 2009 à 21:50:22

                                                          Juste pour t'embêter, le void n'est pas obligatoire en C++ et donc, inutile de s'encombrer avec des mots en plus dans le code, de plus comme tu n'utilises pas l'espace de nommage, ce serait plutôt std::cout et il faut inclure string :p

                                                          Mais en effet, je crois que c'est le plus simple.
                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                            22 décembre 2009 à 21:52:42

                                                            Ah le void n'est pas obligatoire :D
                                                            Pour le string il était inclus plus haut dans mon code et j'avais utilisé using namespace :-°
                                                            J'édite ^^
                                                            • Partager sur Facebook
                                                            • Partager sur Twitter
                                                              22 décembre 2009 à 22:01:05

                                                              (Attention, je n'apporte absolument rien de nouveau au topic)

                                                              std::string bin("11001");
                                                              int dec = 0;
                                                              
                                                              for(int t = 1, i = bin.size()-1; i >= 0; t *= 2)
                                                                 dec += (bin[i--]-'0') * t;
                                                              
                                                              std::cout << dec; // 25
                                                              
                                                              • Partager sur Facebook
                                                              • Partager sur Twitter

                                                              Algorithme de conversion de binaire vers base 10.

                                                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                              • Editeur
                                                              • Markdown