IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Conversion double binaire vers décimal


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné Avatar de mess-mate
    Inscrit en
    Septembre 2008
    Messages
    352
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 352
    Par défaut Conversion double binaire vers décimal
    Bonjour,
    j'ai dû faire une faute de codage.
    Le but de l'opération étant de convertir un double binaire vers du décimal.
    Le nombre décimal est 0.02.
    Voici mon code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    int main()
    {
    //char base_bin[64];
    char base_bin[]="0111101100010100101011100100011111100001011110101001010000111111";
    int pos=strlen((const char*)base_bin)-1;
    int pos2=pos+1;
    double d1=0;
    double d2=0;
    int x=0;
    int y=12;
    char i='1';
     
     
    cout << "strlen of pos =" <<pos+1 <<endl;
    //cout << "pos start at end of string = " << pos << endl;
    cout << "Calculation start at pos : " << y << endl;
     
    while ( pos2 > y )
        {
        unsigned char ch = base_bin[y];
        if ( ch == i) {
     
           d1=pow(2,x);
           cout << "bit = " << ch << " at pos = " << y << endl;
           d2=d2+d1;
           cout << "Value at this pos = " << d1 << "and d2 = " << d2 << endl;
        }
            x++;
            y++;
        }
    //printf ( "Double d2 final = %.8f\n",d2);
    printf ( "Double d2 final = %.2f\n",d2);
    cout<<"final d2 = "<<d2<<endl;
    return 0;
    }
    J'ai tenu compte avec le bit de signe et l'exposant. La mantisse devrait donc être 2 et l'exposant e^-2, si j'ai juste
    Ce code ne calcule que la mantisse pour commencer.
    Et j'arrive pas à trouver ce fameux '.' qui devrait se trouver en dernière position de la mantisse ?

  2. #2
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juin 2006
    Messages
    85
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 85
    Par défaut
    Bonsoir,

    Je pense que le plus simple est d'utiliser une boucle "for" plutôt que "while", ça évite de rajouter "manuellement" les incrémentations à chaque boucle.
    La variable "i" est inutile puisqu'elle contient une constante utilisée une seule fois.
    De même d1 n'est pas nécessaire puisqu'on peut utiliser "+=" au lieu de rajouter la puissance en 2 temps.

    Voilà pour la transformation pur et dur du binaire vers du décimal, pour la mantisse et autre je te laisse te débrouiller :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    int main()
    {
    	char base_bin[]="0111101100010100101011100100011111100001011110101001010000111111";
    	double d2=0;
    	int size = (int)strlen((const char*)base_bin);
     
    	for(int pos=size; pos>0; pos--)
    	{
    		if(base_bin[pos-1] == '1')
    			d2+=pow(2,size-pos);
    	}
     
    	std::cout<<"final d2 = "<<d2<< std::endl;
    	return 0;
    }

  3. #3
    Membre chevronné Avatar de mess-mate
    Inscrit en
    Septembre 2008
    Messages
    352
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 352
    Par défaut
    Après réflexion, il faut pas de point dans ce cas puisqu'il y a pas d'unité.

    Je vais rectifier un peu le codage comme suggéré, merci.

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 474
    Par défaut
    Pour moi, le code en binaire qui se trouve dans base_bin est erroné (s'il s'agit bien d'un double au format IEEE 754). Sinon, je te propose ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #include <iostream>
     
    using namespace std;
     
    int main (void)
    {
        unsigned long int       x;
    //  char                    base_bin[]  = "0111101100010100101011100100011111100001011110101001010000111111";
        char                    base_bin[]  = "0011111110010100011110101110000101000111101011100001010001111011";
        unsigned long long int  d = 0;
     
        for (x=0;x<sizeof(base_bin)-1;++x) { d<<=1; d|=base_bin[x]&1; }
        cout << *(double *)&d << endl;
     
        return 0;
    }

  5. #5
    Membre chevronné Avatar de mess-mate
    Inscrit en
    Septembre 2008
    Messages
    352
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 352
    Par défaut
    Uhh.. ce code binaire (décodage little endian) sur 64 bits vient tout droit d'un fichier dans la ram.
    Le khexedit en binaire pointé sur le premier bit donne bien en 64bits 2.000000E-02.
    Les bits sont représentés comme dans le décodage de khexedit de gauche à droite.
    La proposition avec mon codage et binaire proposé ne marche pas non plus.
    Le codage proposé avec le binaire proposé donne un faux résultat.
    J'arrive pas à trouver où ça coince.

    Il me reste plus qu'une possibilité je pense, c'est de douter de khexedit qui m'a renvoyé le nombre binaire hors normes.

  6. #6
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juin 2006
    Messages
    85
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 85
    Par défaut
    Voilà le décodage IEEE 754 64 bits (comme le propose Obsidian) de ta chaîne (sans les exceptions) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
     
    #include <iostream>
    #include <math.h>
     
    #define TAILLE_SIGNE	1
    #define TAILLE_EXPOSANT	11
    #define TAILLE_MANTISSE	52
     
    unsigned long long ullExtractNumber(char* szNumber)
    {
    	unsigned long long ullResult = 0;
    	int iSize = (int)strlen(szNumber);
     
    	for(int iPos = iSize; iPos > 0; iPos--)
    	{
    		if(szNumber[iPos-1] == '1')
    			ullResult += (int)pow(2, iSize-iPos);
    	}
     
    	return ullResult;
    }
     
    int main()
    {
    	char szBaseBin[]="0111101100010100101011100100011111100001011110101001010000111111";	
    	if(strlen(szBaseBin) != (TAILLE_SIGNE+TAILLE_EXPOSANT+TAILLE_MANTISSE)) return 1;
     
    	char szSigne[TAILLE_SIGNE+1];
    	char szExposant[TAILLE_EXPOSANT+1];
    	char szMantisse[TAILLE_MANTISSE+1];
    	strncpy(szSigne,	szBaseBin,					TAILLE_SIGNE);
    	szSigne[TAILLE_SIGNE] = 0;
    	strncpy(szExposant,	szBaseBin+TAILLE_SIGNE,		TAILLE_EXPOSANT);
    	szExposant[TAILLE_EXPOSANT] = 0;
    	strncpy(szMantisse,	szBaseBin+TAILLE_EXPOSANT,	TAILLE_MANTISSE);
    	szMantisse[TAILLE_MANTISSE] = 0;
     
    	unsigned long long ullSigne		= ullExtractNumber(szSigne);
    	unsigned long long ullExposant	= ullExtractNumber(szExposant);
    	unsigned long long ullMantisse	= ullExtractNumber(szMantisse);
     
    	std::cout << "Signe = " << ullSigne << std::endl;
    	std::cout << "Exposant = " << ullExposant << std::endl;
    	std::cout << "Mantisse = " << ullMantisse << std::endl;
     
    	double dResult = pow(-1, (int)ullSigne) * ullMantisse * powl(2, (int)(ullExposant-1023));
     
    	std::cout << "Result = " << dResult << std::endl;
    	return 0;
    }
    Le résultat donne 1.09722e+304 ce qui est à l'opposé du résultat attendu.
    Soit le codage n'est pas le bon, soit le résultat n'est pas codé sur les 64 bits, mais peut-être sur 8 ou autre...

  7. #7
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par mess-mate Voir le message
    Uhh.. ce code binaire (décodage little endian) sur 64 bits vient tout droit d'un fichier dans la ram.
    Le khexedit en binaire pointé sur le premier bit donne bien en 64bits 2.000000E-02.
    Les bits sont représentés comme dans le décodage de khexedit de gauche à droite.
    Oui mais:
    "0111101100010100101011100100011111100001011110101001010000111111"
    vient d'ou ?
    D'autre part, il ne correspond pas à 0x7E14AE47E17A943F mais à 0x7B14AE47E17A943F

    1 bit de signe: 0 (+)
    11 bits d'exposants: 0x7B1 soit 1969 donc: 2^946 => C'est pas bon pour avoir 0,02 !!


    Maintenant, si c'est une copie des octets à la suite :
    "01111011" "00010100" "10101110" "01000111" "11100001" "01111010" "10010100" "00111111" ?

    Alors le nombre binaire n'est pas celui au dessus... mais (en little-endian):
    0011111110010100011110101110000101000111101011100001010001111011
    soit: 0x3F947AE147AE147B

    1 bit de signe: 0 (+)
    11 bits d'exposant: 0x3F9 soit 2^-6 (déjà bien plus plausible)
    52 bits de mantisse: 1.(fraction) 0x47AE147AE147B soit... 2^-1 + 2^-2 + 2^-4+2^-5...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [QST] conversion string binaire vers void *
    Par hannibal.76 dans le forum Débuter
    Réponses: 4
    Dernier message: 09/07/2012, 11h53
  2. Conversion chaine binaire vers TimeDate48
    Par clem67 dans le forum VB.NET
    Réponses: 4
    Dernier message: 25/05/2011, 11h13
  3. conversion de decimale vers binaire et vice versa
    Par Abdelkaoui dans le forum Qt
    Réponses: 1
    Dernier message: 17/04/2008, 11h53
  4. conversion de int vers binaire
    Par ben83 dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 12/02/2007, 19h19
  5. Pb de conversion: double[] vers un vector type???
    Par hycsos dans le forum SL & STL
    Réponses: 4
    Dernier message: 15/01/2006, 07h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo