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 :

problème avec unsigned int


Sujet :

C

  1. #1
    Membre averti

    Profil pro
    Enseignant
    Inscrit en
    Juillet 2003
    Messages
    296
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Juillet 2003
    Messages : 296
    Points : 441
    Points
    441
    Par défaut problème avec unsigned int
    Bonjour !
    En testant un bout de code, concernant les types de variables signées ou non signées, j'ai remarqué un truc que je ne m'explique pas.

    si je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    unsigned short s;
    s = -1 ;//pour forcer le MSB à 1
    printf("valeur = %d", s);
    j'ai bien une valeur non signée de 65535.

    Or, en reprenant le même code, mais en changeant short par int…
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    unsigned int i;
    i = -1 ;//pour forcer le MSB à 1
    printf("valeur = %d", i);
    Il me sort -1 !

    J'ai beau chercher la cause, je ne la comprends pas.
    Pouvez-vous éclairer ma lanterne ?

    Merci !

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonsoir,


    Citation Envoyé par Big Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    unsigned int i;
    i = -1 ;//pour forcer le MSB à 1
    printf("valeur = %d", i);
    Il me sort -1 !
    Le format %d correspond à un entier signé (signed int), tu indiques au compilateur de considérer i en tant que tel, il est donc normal que tu obtiennes -1.
    printf("valeur = %u", i); par contre t'affichera bien la valeur que tu attends

    Attention aussi à :
    Citation Envoyé par Big Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    unsigned short s;
    s = -1 ;//pour forcer le MSB à 1
    printf("valeur = %d", s);
    j'ai bien une valeur non signée de 65535.
    Comme dit, %d est pour un signed int. Or tu traites un short.
    Rajoutes un h devant %hd et tu observeras le même effet

    N"hésite pas à jeter un coup d’œil au tableau de la documentation.

  3. #3
    Membre averti

    Profil pro
    Enseignant
    Inscrit en
    Juillet 2003
    Messages
    296
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Juillet 2003
    Messages : 296
    Points : 441
    Points
    441
    Par défaut
    Merci. Mais j'ai dû mal m'exprimer. Le but ici n'est pas d'afficher la valeur avec un %d ou autre. Ce que je ne comprends pas, c'est pourquoi quand je mets -1 dans le unsigned int, la valeur reste signée. J'avais pensé à l'erreur de formatage, aussi j'ai testé ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    unsigned int i;
    i=-1;
    (i==-1) ? printf("signed") : printf ("unsigned");
    Je pars toujours du principe que si je mets une valeur négative dans un unsigned , j'ai une valeur dans la fin du range. Donc, logiquement, i ne sera pas égal à -1... or, le code affiche signed !
    C'est ça qui me chiffonne un peu. Mais tu as raison pour le reste, je n'ai pas mis les bons formats

  4. #4
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Points : 7 842
    Points
    7 842
    Par défaut
    La valeur stockée dans la variable est la même, c'est son interprétation qui change:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    unsigned int i= -1;
    int j= -1;
    printf("i=%u/%d/%ld is %ssigned\n",i,i,(long)i,(long)i==-1L ?"":"un");
    printf("j=%u/%d/%ld is %ssigned\n",i,i,(long)j,(long)j==-1L ?"":"un");
    donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    i=4294967295/-1/4294967295 is unsigned
    j=4294967295/-1/-1 is signed
    ɹǝsn *sıɹɐlos*

  5. #5
    Membre éclairé
    Inscrit en
    Juillet 2012
    Messages
    231
    Détails du profil
    Informations forums :
    Inscription : Juillet 2012
    Messages : 231
    Points : 870
    Points
    870
    Par défaut
    Citation Envoyé par Big Voir le message
    J'ai beau chercher la cause, je ne la comprends pas.
    Pouvez-vous éclairer ma lanterne ?
    Ton littéral -1 est un int, probablement 32-bit donc en hexa ça donne 0xFFFFFFFF.
    Quand tu l’affectes à un short, probablement sur 16-bit, ça va être tronqué en 0xFFFF.
    Ensuite, tu l’affiche avec %d donc en tant que int, ça va être interprété comme 0x0000FFFF => 65535.

    Quand tu affectes -1 à un unsigned int ça reste 0xFFFFFFFF, pas de pertes.
    Ensuite, tu l’affiches avec %d tu as 0xFFFFFFFF et c’est interprété en tant que nombre signé donc ça donne -1.


    Au passage, pour forcer les bits à 1, je préfère
    plutôt que
    Ça évite des warnings du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    warning: implicit conversion changes signedness: 'int' to 'unsigned int' [-Wsign-conversion]
        i = -1;
          ~ ^~

  6. #6
    Membre averti

    Profil pro
    Enseignant
    Inscrit en
    Juillet 2003
    Messages
    296
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Juillet 2003
    Messages : 296
    Points : 441
    Points
    441
    Par défaut
    Merci ! J'ai appris quelque chose.
    Désolé de vous avoir embêté avec ce cas trivial

  7. #7
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Si l'objectif en mettant tous les bits à 1 est en d'avoir la plus grande valeur possible, on devrait utiliser les constantes de limits.h :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <limits.h>
    #include <stdlib.h>
    #include <stdio.h>
     
    int main(void)
    {
    	unsigned short a = USHRT_MAX;
    	printf("%hd = %X", a, a);
    	return 0;
    }

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Citation Envoyé par jlliagre Voir le message
    La valeur stockée dans la variable est la même, c'est son interprétation qui change:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    unsigned int i= -1;
    int j= -1;
    printf("i=%u/%d/%ld is %ssigned\n",i,i,(long)i,(long)i==-1L ?"":"un");
    printf("j=%u/%d/%ld is %ssigned\n",i,i,(long)j,(long)j==-1L ?"":"un");
    donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    i=4294967295/-1/4294967295 is unsigned
    j=4294967295/-1/-1 is signed
    Est-ce un code 64 bits LP64?
    Parce qu'en 32 bits, j'ai ceci, et je parie que j'aurais la même sortie en 64 bits sous Windows (LLP64):
    Code X : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    i=4294967295/-1/-1 is signed
    j=4294967295/-1/-1 is signed
    Par contre, le code suivant donne la bonne sortie:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    printf("i=%u/%d/%lld is %ssigned\n", i, i, (long long)i, (long long)i==-1LL ?"":"un");
    printf("j=%u/%d/%lld is %ssigned\n", i, i, (long long)j, (long long)j==-1LL ?"":"un");
    Edit: Bien sûr, en ILP64, ça foirerait à nouveau.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Points : 7 842
    Points
    7 842
    Par défaut
    Oui, bien vu, je suis effectivement bien en LP64.
    ɹǝsn *sıɹɐlos*

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

Discussions similaires

  1. Problème avec variable int qui vaut soit 0 soit 1
    Par gkn28 dans le forum Langage
    Réponses: 4
    Dernier message: 21/04/2013, 18h55
  2. [XL-2007] Problème avec fonction Int()
    Par jgfa9 dans le forum Macros et VBA Excel
    Réponses: 11
    Dernier message: 21/05/2010, 09h47
  3. Problème avec unsigned long long
    Par spiner900 dans le forum Débuter
    Réponses: 2
    Dernier message: 19/02/2009, 20h37
  4. Problème avec fct Int()
    Par freefly3 dans le forum Macros et VBA Excel
    Réponses: 9
    Dernier message: 05/12/2008, 09h04
  5. Réponses: 7
    Dernier message: 28/03/2006, 23h09

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