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 :

int et unsigned int


Sujet :

C

Vue hybride

Biosox int et unsigned int 03/12/2009, 10h10
Jenna Compilateur mal réglé,... 03/12/2009, 10h24
Biosox Bonjour, merci pour ta... 03/12/2009, 10h38
Jenna dans le 1er cas (unsigned... 03/12/2009, 10h48
Biosox merci pour ces précisions.... 03/12/2009, 11h17
diogene Ce ne sont que des warnings... 03/12/2009, 11h28
Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de Biosox
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    298
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 298
    Par défaut int et unsigned int
    Bonjour.

    que se passe-t'il si j'écris:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    unsigned int i = -1;
    Est-ce que ça va poser un problème?
    en tout cas le compilateur l'accepte et ça a l'air de marcher.

    je m'explique:
    je veux écrire une fonction dont la valeur de retour est supposée être un entier positif (par exemple une fonction qui calcule une distance... une distance ça ne peut pes être négatif par définition. du coup ma fonction va retourner un unsigned int
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unsigned int calcul_distance();
    si il y a une erreur dans ma fonction, ça m'arrange de retourner une valeur du genre -1, -2, etc... (si mes int sont codés sur 32 bits, si je retourne -1, ça va en fait retourner 0xffffffff, soit 4 milliards et des poussières... c'est une "distance" que je peux raisonnablement considerer comme fausse)

    que va-til se passer avec le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    unsigned int d = 0;
    d = calcul_distance();
    if(d == -1){
    printf("error");
    }
    il compile et il marche... j'ai même pas de warning pour la comparaison entre 'd' et '-1'
    Mais je me pose la question: Est-ce que ça va marcher avec tous les compilos?
    Et si oui, a quoi ça sert d'avoir 2 types distinct (int et unsigned int) alors que visiblement ils sont traités pareil?

    merci!

    a+

  2. #2
    Membre chevronné Avatar de Jenna
    Inscrit en
    Décembre 2009
    Messages
    272
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Décembre 2009
    Messages : 272
    Par défaut
    Compilateur mal réglé, normallement, il devrait crier et emettre au moins un warning en disant en substance "comparaison entre un nombre signé et un nombre non signé".

    A quoi cela sert d'avoir 2 type distincts, pour les traiter différemment.

    essaye
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    unsigned int test1 = -2;
    test1 <<= 1;
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int test1 = -2;
    test1 <<= 1;
    tu auras 2 résultats différents.

  3. #3
    Membre éclairé Avatar de Biosox
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    298
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 298
    Par défaut
    Bonjour,
    merci pour ta répnse.
    Qu'entends-tu par résultats différents?

    J'ai fait:
    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
    int main()
    {
      unsigned int test1 = -2;
      int test2 =-2;
     
      test1 <<= 1;
      test2 <<= 1;
     
      printf("test1  %08X  %d  %u\n", test1, test1, test1);
      printf("test2  %08X  %d  %u\n", test2, test2, test2);
     
      if( test1 < test2 ){
        printf("smaller\n");
      }
     
      if( test1 > test2 ){
        printf("bigger\n");
      }
     
      if( test1 == test2 ){
        printf("equal\n");
      }
     
      return 0;
    }
    et mon output:
    test1 FFFFFFFC -4 4294967292
    test2 FFFFFFFC -4 4294967292
    equal
    Bon... je suppose que printf fait un cast si je lui donne un unsigned pour un %d, et inversément... mais le 0x08X semble montrer que les 2 variables sont traitées de la même façon, non?

  4. #4
    Membre chevronné Avatar de Jenna
    Inscrit en
    Décembre 2009
    Messages
    272
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Décembre 2009
    Messages : 272
    Par défaut
    dans le 1er cas (unsigned int), la nouvelle valeur est 4294967292
    dans le 2ème cas (int), la nouvelle valeur est -4

    donc 2 valeurs sémantiquement différentes (même si leur représentation en mémoire est identique)

    au passage, j'ai un warning du compilateur
    warning C4245: 'initialisation' : conversion de 'int' en 'unsigned int', incompatibilité signed/unsigned

  5. #5
    Membre éclairé Avatar de Biosox
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    298
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 298
    Par défaut
    merci pour ces précisions.
    je vais essayer de voir pourquoi j'ai pas de warnings de mon coté.

  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
    Ce ne sont que des warnings informatifs indiquant qu'une opération demandée peut ne pas faire ce que pense le programmeur.

    Par contre, le comportement est bien défini : la conversion entier signé -> entier non signé donne un résultat parfaitement prévisible.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
      unsigned int test1 = -2;
      int test2 =-2;
    ...
    if( test1 == test2 ){
        printf("equal\n");
      }
    Voila un test qui ne teste pas grand chose : dans une telle expression, test1 et test2 subissent avant évaluation les conversions standard : l'opérande de type int (test2) est transformée en une valeur de type unsigned int (type de test1). Il n'est donc pas étonnant d'avoir pour résultat "vrai".

    Par contre la situation diffère ici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
      unsigned char test1 = -2;
      int test2 =-2;
    ...
    if( test1 == test2 ){
        printf("equal\n");
      }
    Ici la comparaison répondra "Faux", car cette fois, c'est test1 qui sera converti en le type de test2 (int) avant comparaison (pourvu que les valeurs d'un unsigned char puissent être représentées dans un int, sinon, on aura conversion en unsigned int des deux opérandes).

    On voit que la comparaison signed/unsigned est un peu délicate ce qui justifie l'émission d'un avertissement.

  7. #7
    Membre chevronné Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Par défaut
    En faite, les choses on été faite pour que les opération ne diffère pas, pour une grande partie.

    Je crois que les opération qui diffère sont >,<,>=,<=,*,\. Pour le reste, c'est tout pareil.

    A savoir que (unsigned char) -1 == 255. C'est une histoire de complément !

    Un entier signé, c'est 1 bit de signe, et les autres de valeurs. Mais si on code les valeurs comme pour les positif, on à deux 0 oO ! Du coup, on procède différemment :

    Donc pour trouver un nombre négatif, on hôte 1 est on inverse tous les bits :
    1 = 00000001 -> 00000000 -> 111111111 = -1 (ou 255).

    En gros, dans le deuxième cas, on compare :
    0xFFFE == 0x[00]FE.

Discussions similaires

  1. afficher un unsigned int
    Par m0ul3sh0t dans le forum C
    Réponses: 10
    Dernier message: 13/11/2007, 14h39
  2. unsigned int dans un vector
    Par Mindiell dans le forum SL & STL
    Réponses: 6
    Dernier message: 12/09/2007, 11h07
  3. Réponses: 1
    Dernier message: 15/02/2007, 17h32
  4. int, unsigned int, et la fonction pow
    Par salseropom dans le forum C
    Réponses: 11
    Dernier message: 22/12/2006, 17h53
  5. [WMI] Variant de type Unsigned Int 64 ...
    Par phplive dans le forum API, COM et SDKs
    Réponses: 3
    Dernier message: 09/05/2006, 20h15

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