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 :

Affichage d'un nombre négatif en hexadécimal


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    ceo
    Inscrit en
    Août 2005
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : ceo

    Informations forums :
    Inscription : Août 2005
    Messages : 62
    Par défaut Affichage d'un nombre négatif en hexadécimal
    Bonjour,

    je veux afficher un nombre en hexadécimal, tout va bien tant que le nombre est positif, mais quand il est négatif, ça ne va plus, par exemple quand ma variable
    vaut -1 (en décimal) la console affiche FFFFFFFF en hexadécimal, au lieu de -1, comment faire pour qu'elle m'affiche -1? (A part, tester si la valeur est inférieure à 0 auquel cas on affiche la valeur absolu en hexadécimal avec un moins devant, ce qui me semble un peu lourd.)

    Merci d'avance.

  2. #2
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Tu as répondu toi même à ta question. La représentation en hexa de -1 est effectivement 0xFFFFFFF (pour une variable de taille 32 bits) car les nombres sont codés en complément à 2. Si tu veux afficher en signe + amplitude, il faut effectivement déterminer le signe, extraire l'amplitude et ensuite afficher le tout.

    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
    #include <limits.h>
    #include <stdio.h>
    #include <stdlib.h>
     
    void print_hexa(int n)
    {
        printf("%d =\t %s%X\n", n, n<0 ? "-" : "", abs(n));
    }
     
    int main(void)
    {
        print_hexa(255);
        print_hexa(-255);
        print_hexa(-1);
        print_hexa(1);
        print_hexa(INT_MAX);
        print_hexa(-INT_MAX);
        return 0;
    }
    Je méfierai des nombres aux limites de la capacité d'un int... Mais ça a l'air de marcher.

  3. #3
    Membre confirmé
    Profil pro
    ceo
    Inscrit en
    Août 2005
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : ceo

    Informations forums :
    Inscription : Août 2005
    Messages : 62
    Par défaut
    Ok, merci de ta réponse. Mais je ne comprends quand même pas pourquoi en hexadécimal les nombres sont représentés en complément à deux et en décimal non.

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 484
    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 484
    Par défaut
    Bonjour,

    Citation Envoyé par simnitch Voir le message
    Ok, merci de ta réponse. Mais je ne comprends quand même pas pourquoi en hexadécimal les nombres sont représentés en complément à deux et en décimal non.
    C'est parce que ton ordinateur utilise en interne le « binaire naturel », lui-même dû au fait qu'il emploie des compteurs, qui sont formés d'une cellule par chiffre.

    C'est exactement de la même façon qu'un compteur kilométrique neuf affichera « 9999999 » si tu fais un kilomètre en marche arrière, puis « 9999998, 9999997, 9999996… » pour « -2, -3, -4… ».

    Bien sûr, si tu essaies dans les faits, tu t'apercevras que le compteur de ta voiture est protégé contre ce genre de fraude, mais il ne l'est que par un dispositif additionnel.

    À noter que les nombres à virgule flottante (float ou double) qui, en C, suivent la norme IEEE 754, sont eux complètement artificiels et utilisent une notation « signe + valeur absolue ».

  5. #5
    Membre chevronné
    Homme Profil pro
    Cadre informatique
    Inscrit en
    Avril 2013
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Cadre informatique

    Informations forums :
    Inscription : Avril 2013
    Messages : 183
    Par défaut
    En fait, il s'agit d'un petit souci d'électronique numérique

    Prenons par exemple:
    10(10) signifie valeur 10 en base décimale
    10(2) signifie valeur 10 en base 2 = binaire
    Ce ne sont pas les mêmes valeurs. Pour le voir, il faut passer dans la même base les 2 valeurs!!
    10(2) = 1*2^1 + 0*2^0 = 2 => 10 en binaire signifie 2

    Voilà à quoi cela va nous servir:

    10(10) = 1010(2) = A(16)

    Comme tu le vois avec cet exemple, la base décimale que tout le monde connaît est comme qui dirait "pourrie" pour un ordinateur. Lui, il prend que des 0 ou des 1 alors autant que cela soit simple.
    La base 2 et 16 sont reliées par la technique simple suivante => 4 chiffres en base 2 donne 1 chiffre en base 16 (oui oui A, B,..., E, F sont des "chiffres" en hexadécimal )

    Ensuite, le complément à 2 notons le (C2) n'est là que pour représenter les nombres binaires en tant que positifs ou négatifs. la relation simple est que:
    la somme de ton chiffre complémenté à 2 avec la valeur absolue de ton chiffre dans sa base normale donnera toujours 0! (mais dans quoi je suis parti moi... )
    Exemple: 0xFFFFFFFF donne -1 car
    FFFFFFFF = 11111...1111 (32 fois)
    on lui ajoute 1
    on obtient:
    (1)000...0000 (32 chiffres 0 et une retenue que l'on ne prend pas en compte
    soit: 0!

    La manipulation est plus complexe mais je te laisse aller voir un guide pour comprendre comment passer qu'un hexa à son complément à 2

    Et donc, après ce cours de 3 pages et demi de long, l'ordinateur ne fonctionne qu'en 0 et 1 mais 4 bits permettent de n'en faire qu'un en hexa.
    Ça permet juste d'afficher une valeur plus digeste à l'utilisateur. Après faut comprendre la logique cachée derrière cela et donc je te renvoie ci-dessus

    Désolé

  6. #6
    Membre confirmé
    Profil pro
    ceo
    Inscrit en
    Août 2005
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : ceo

    Informations forums :
    Inscription : Août 2005
    Messages : 62
    Par défaut
    Merci pour vos réponses détaillées, désolé je suis peut-être un peu lent, mais bien que maîtrisant les changements de base, je ne comprends pas pourquoi -1(2) ne m'affiche pas 4294967295 en décimal au même titre qu'il s'écrit FFFFFFFF en hexadécimal puisque les nombres sont codés en complément à deux.

  7. #7
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 484
    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 484
    Par défaut
    Citation Envoyé par simnitch Voir le message
    Merci pour vos réponses détaillées, désolé je suis peut-être un peu lent, mais bien que maîtrisant les changements de base, je ne comprends pas pourquoi -1(2) ne m'affiche pas 4294967295 en décimal au même titre qu'il s'écrit FFFFFFFF en hexadécimal puisque les nombres sont codés en complément à deux.
    Si. C'est bien le cas. Essaie ceci, en ignorant les éventuels warnings :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <stdio.h>
     
    int main (void)
    {
        unsigned long int x = -1;
     
        printf ("%lu\n",x);
        return 0;
    }
    … et admire le résultat.

    En fait, si on considère que sur un compteur kilométrique, « 999999 » peut signifier soit « Un million de kilomètre moins 1 », soit « -1 kilomètre », on fait de même avec les compteurs informatiques : les circuiteries arithmétiques ne font aucune différence entre un nombre signé et non signé car ils se traitent de la même manière : ce n'est qu'au moment d'examiner le résultat et de prendre une décision que l'on considéra qu'ils sont intrinsèquement signés ou non. En assembleur, toutes les instructions de branchment conditionnel ont leurs pendants signés et non signés.

    Cela signifie qu'on divise en deux l'intervalle des nombres représentables. Si on fait encore une fois le parallèle avec le compteur kilométrique, les nombres de « 000000 » à « 499999 » seraient positifs et les nombres de « 500000 » à « 999999 » seraient négatifs, avec « 999999 = -1 » et « 500000 = … -500000 ».

    Dans cet exemple, quelque soit la largeur du compteur, les nombres commençant par « 0 », « 1 », « 2 », « 3 » ou « 4 » seraient donc toujours positifs et ceux commençant par « 5 », « 6 », « 7 », « 8 » ou « 9 » seraient négatifs.

    Or, et c'est ça qui est très intéressant, nous travaillons en binaire, donc avec seulement deux chiffres ! Les nombres positifs commencent donc toujours par « 0 » et les négatifs par « 1 ». Par conséquent, le bit de poids fort d'un entier binaire est — de fait — toujours l'image de son signe si on décide de le considérer comme relatif.

  8. #8
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Ton ordinateur ne connait qu'une suite de niveaux logiques (haut et bas). La manière donc on l'affiche n'est qu'une histoire de convention. On a décidé d'écrire des 0 et des 1 pour représenter ces états logiques. On parle de base binaire. On peut grouper ces nombres par 3 ou par 4 pour faire des nombres octaux et hexadécimaux. Il n'y a pas de signe dans ces bases, juste un nombre. On alors plus de symboles pour représenter les nombre (1 à 9 puis A à F mais on aurait pu choisir 16 lettres ou des formes telles que des étoiles ou des triangles).

    Les nombres décimaux non signés n'ont rien à voir avec cette représentation. On a juste posé une nouvelle manière de coder un nombre avec des états logiques. On a utilisé une somme de puissances de deux pour cela.

    Enfin, on s'est dit "tiens, et les nombres signés ?". On alors inventé d'autres conventions pour cela : bit de signe + amplitude, complément à 1, complément à 2. Ces conventions te disent comment interpréter un nombre hexa (ou binaire ou octal, c'est pareil).

    Prenons une suite binaire (sur 3 bits) : 111. En octal, ça fait 7, en hexa aussi. Et en décimal ? Et bien ça dépend : en non signé, ça fait 7; en signe + amplitude, ça fait -3; en C2 ça fait -1.

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

Discussions similaires

  1. Affichage de nombres négatifs dans QLabel
    Par ChMeessen dans le forum Qt
    Réponses: 8
    Dernier message: 27/01/2010, 11h00
  2. Affichage d'un nombre négatif
    Par looping dans le forum Langage
    Réponses: 8
    Dernier message: 28/04/2008, 08h48
  3. Affichage d'un nombre binaire
    Par Jero13 dans le forum C
    Réponses: 5
    Dernier message: 05/12/2005, 22h17
  4. [D7 Ent. / XP] Trunc() sur un nombre négatif
    Par Magnus dans le forum Langage
    Réponses: 14
    Dernier message: 17/06/2005, 16h45
  5. [68000] EXT nombre négatif
    Par fastzombi dans le forum Autres architectures
    Réponses: 2
    Dernier message: 02/05/2004, 12h17

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