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 :

signed char et unsigned char


Sujet :

C

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 11
    Par défaut signed char et unsigned char
    Bonjour,

    Je voudrais savoir comment au niveau binaire une comparaison entre signed et unsigned s'effectue ?

    exemple :
    unsigned char uc; char sc;
    Je lis que l'égalité ci-dessus ne sera jamais vraie et je ne vois pas comment ça fonctionne au niveau binaire.
    Je sais qu'un nombre négatif est stocké sous la forme de son complément à deux : par exemple sur un octet, -5 sera stocké comme 1111 1011.
    Donc EOF (-1/int) sur un octet - pour simplifier - donne : 1111 1111.
    uc qui est convertit en int, reçoit donc : 1111 1111
    Ce sont bien ces deux valeurs qui sont comparées et je ne vois pas comment le compilateur voit la différence; car si c'était un (signed) char qui recevait le EOF, le motif binaire serait identique ( et là pourtant ça marche alors qu'avec l'unsigned char, le compilo me dit - à juste titre - que la comparaison sera toujours fausse etc....

    Donc au fond comment fait-il la différence ? y-a t'il encore une autre conversion derrière ?
    J'ai parcouru qq pdf d'architecture mais je ne comprends pas en fait, et toute aide serait grandement appréciée !

    merci d'avance

  2. #2
    Membre éprouvé
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2008
    Messages
    143
    Détails du profil
    Informations personnelles :
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2008
    Messages : 143
    Par défaut
    Donc EOF (-1/int) sur un octet - pour simplifier - donne : 1111 1111.
    uc qui est convertit en int, reçoit donc : 1111 1111
    EOF est bien un type INT et c'est ce qui te pose probleme aparement.

    Es-tu sur que c'est UC qui sera converti en INT ?
    Dans ce cas es-tu certains du fait que si UC contient 1111 1111 après conversion il contiendra :
    1111 1111 1111 1111... (depend sur 4 octets ou 2 octets.)


    En réalité si c'est UC qui est convertis :

    Si il est de type Unsigned CHAR alors le padding se fera a grand coup de 0
    tu auras donc 0000 0000 0000 0000 0000 0000 1111 1111 (qui va donner 255 en type INT).

    Si UC est un SIGNED CHAR alosr il sera paddé a grand coup de 1 :
    tu auras donc 1111 1111 1111 1111 1111 1111 ... etc...
    soit -1 en type INT



    C'est donc tout à fait normal que ça dise que c'est correct avec un SIGNED et non avec un UNSIGNED.

    Cela vien du fait qu'un nombre négatif est représenté avec le poids fort a 1.
    Et de ce fait si tu essay de rendre le type "plus grand" alors il faut forcer le poids fort à 1 et donc les bits intermédiaire pour garder la même valeur.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 11
    Par défaut
    Merci beaucoup, je ne voyais pas le bout de cette question !

    Tu as raison, je n'aurais pas dû me limiter à un octet puisque uc est convertit en int ( car EOF est int ).C'est d'ailleurs pour ça que getchar convertit la saisie en int.

    C'est avec les bits au dessus de l'octet faible qu'on peut voir la différence...

  4. #4
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Ce n'est pas une question de représentation des nombres, mais du langage lui-même

    Pour évaluer l'expression uc==EOF, tout se passe comme si :

    1 - La valeur de uc, un unsigned char donc un type "petit entier" par rapport à int, est promue en int en conservant la même valeur.
    La valeur obtenue, de type int, reste positive ou nulle

    2 - la comparaison est faite entre deux int : cette valeur positive ou nulle et EOF qui est un int négatif

    3-le résultat est toujours faux.


    Une autre possibilité qui pourrait arriver est d'avoir, à la place de uc, une valeur us de type unsigned short.

    1- Si les int peuvent représenter toutes les valeurs des unsigned short, le processus est celui décrit ci-dessus.

    2- Mais si ce n'est pas le cas (lorsque les unsigned short sont de même taille que les int) , us sera promu en unsigned int (avec une valeur inchangée).
    - Alors, cette fois, on compare un unsigned int et un int (EOF). C'est le int , donc EOF, qui sera converti en unsigned int.
    - Il y a alors une valeur de us pour laquelle le résultat est vrai.
    (Par exemple, si EOF == -1 et si les unsigned short et les int sont sur 16 bits, EOF est converti en unsigned int avec la valeur 2^^16-1, valeur que peut prendre us)

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 11
    Par défaut
    Citation Envoyé par diogene Voir le message
    Ce n'est pas une question de représentation des nombres, mais du langage lui-même

    Pour évaluer l'expression uc==EOF, tout se passe comme si :

    1 - La valeur de uc, un unsigned char donc un type "petit entier" par rapport à int, est promue en int en conservant la même valeur.
    La valeur obtenue, de type int, reste positive ou nulle

    2 - la comparaison est faite entre deux int : cette valeur positive ou nulle et EOF qui est un int négatif

    3-le résultat est toujours faux.
    Merci pour le complément...donc dernière question pour pour bien clarifier :

    la conversion de UC en int se fait bien après qu'il ait reçu la valeur de EOF ?
    (Il reçoit -1 puis est paddé par des 0 )

  6. #6
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Citation Envoyé par sitamob Voir le message
    Merci pour le complément...donc dernière question pour pour bien clarifier :

    la conversion de UC en int se fait bien après qu'il ait reçu la valeur de EOF ?
    (Il reçoit -1 puis est paddé par des 0 )
    Je ne comprend pas ce que tu veux dire : avec l'expression uc==EOF, uc ne reçoit aucune valeur et garde celle qu'il avait avant.

    Précise le code dont tu parles.

    Si tu parles de uc = EOF, alors, pour faire l'assignation, il faut convertir EOF en le type unsigned char.
    Ceci ne dépend pas de la représentation des nombres (entre parenthèses, les nombres signés sont souvent représentés en complément à deux, mais deux autres représentations sont possibles).

    La règle est d'ajouter ou de soustraire à EOF la valeur maximum+1 d'un unsigned char autant de fois que nécessaire pour que la valeur obtenue soit dans la plage d'un unsigned char.

    Si ton unsigned char est sur 8 bits, la valeur à ajouter ou à soustraire est 256.
    Avec EOF == -1, uc prend la valeur -1+256 = 255 soit tous les bits à 1
    Si tu écris uc = 513 alors uc prend la valeur 513-256-256 =1

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 11
    Par défaut
    C'est noté pour le code,merci
    En effet, j'ai dévié :
    du premier problème qui était de comprendre comment deux motifs binaires qui me paraissaient identiques pouvaient être différents.
    d'où .
    à un autre mais sans le préciser
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while((uc= getchar())!=EOF)
    où je voulais savoir si uc était convertit en int avant l'affectation, auquel cas en changeant de taille il aurait pu recevoir le -1 en motif binaire ou après l'affectation, auquel cas il aurait reçu 8 bits à 1 (255) et se serait "remplit" de zéro après.
    C'est plus clair à présent grâce à vos explication,s c'est EOF qui s'adapte (est convertit) en unsigned char puis placé dans uc convertit en int.

    J'espère ne pas vous avoir trop pris la tête et merci encore !

  8. #8
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Détaillons, parce que le mécanisme est toujours le même en C et qu'il faut le comprendre :
    L'opérateur != compare deux valeurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    uc= getchar()
    // et
    EOF
    Pour la première valeur, uc= getchar(), l'évaluation de uc est faite comme je l'ai décrite dans un message précédent.
    Ce que je n'avais pas précisé, c'est la valeur finale de cette expression, car uc= getchar() possède une valeur et un type (comme toute valeur en C; toute expression en C possède une valeur). C'est facile, elle prend pour valeur et pour type celui de uc (donc unsigned char).

    Ceci dit, je compare cette valeur unsigned char et EOF (de type int)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <valeur unsigned char> == EOF ???
    qui, à son tour, est évaluée suivant les règles décrites précédemment.

    J'espère ne pas vous avoir trop pris la tête
    Pas de problèmes cette question est suffisamment importante.

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

Discussions similaires

  1. Réponses: 9
    Dernier message: 16/07/2008, 11h01
  2. [Clé de registre] Conversion char* vers unsigned char*
    Par The Lord of Nesquik dans le forum C
    Réponses: 7
    Dernier message: 03/07/2006, 23h30
  3. Types : char vs. unsigned char
    Par Herode dans le forum C++
    Réponses: 3
    Dernier message: 15/02/2006, 21h39
  4. vector<unsigned char> et unsigned char* : conversion ?
    Par zax-tfh dans le forum SL & STL
    Réponses: 5
    Dernier message: 15/01/2006, 10h43
  5. char et unsigned char
    Par jobherzt dans le forum C++
    Réponses: 8
    Dernier message: 11/02/2005, 00h24

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