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 de cast


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 855
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 855
    Par défaut problème de cast
    Bonjour,

    j'ai les variables suivantes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    unsigned char buf[2];
    int val; // entier signé sur deux octets
    Je voudrais copier la valeur qui est dans buff[] dans la variable val.
    buff[0] contient l'octet de poids fort et buff[1] contient l'octet de poids faible.

    Comment dois-je vais ma copie ?

    comme ça ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    val =  buf[1];
    val |=  ((int)buf[0]) << 8;
    J'ai quelque doute sur le castage : si buf[0] = 0xFF, alors ((int)buf[0]), ça donne quoi ? 255 ou -127 ?

    Quelles sont les règles pour le castage au niveau du signe ?

  2. #2
    Membre très actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2010
    Messages
    254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2010
    Messages : 254
    Par défaut
    Je m'egare peut-etre mais ne pourrais tu pas stocker ces variable dans une union? Vu qu'elle auront la meme adresse, tu pourras acceder aux valeurs de ton tableau via ton int...

  3. #3
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    Dans ton exemple ((int)buf[0]) sera un int qui vaudra 255.

    Par contre si buf[] avait été déclaré en "signed char", ((int)buf[0]) aurait valu -1 (c'est à dire, en hexa, 0xffffffff). C'est le "signedness" de buf[] qui va déterminer comment le signe est "expansé" lors du cast.

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 855
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 855
    Par défaut
    merci,

    Ma fonction doit donc bien fonctionner...

    Par contre que se passe t-il sur ces deux cas ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    unsigned char myChar;
    signed char mySChar;
     
    mySChar = -1;
    myChar = (unsigned char)mySChar; // ???
     
    myChar = 255;
    mySChar= (signed char)myChar ; // ???
     
    // copie de la valeur hexa
    myChar = 255;
    mySChar = myChar; // comment faire pour que le compilateur ne fasse pas de warning ?

  5. #5
    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
    Pour des char de 8 bits :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    mySChar = -1;
    myChar = (unsigned char)mySChar; // ???
    myChar = 256+mySChar = 255


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    myChar = 255;
    mySChar= (signed char)myChar ; // ???
    mySChar dépend de l'implémentation

    Pour revenir au premier post :

    Dans l'expression buf[0] << 8, l'opérande buf[0] est promu en int automatiquement (donc le cast est inutile) en conservant sa valeur.
    Si les int de la machine sont sur plus de 16 bits, cette expression est égale à buf[0]*256.
    Par exemple, si on a unsigned char buf[2]= {0xA4,0xe3} = {164,227}, buf[0]) << 8 a pour valeur 164*256 = 41984.
    et au total, le code posté donnera val = buf[0]*256+buf[1] soit dans l'exemple 41984+227 = 42211 (ce qui n'est pas la valeur espérée).
    Si les int sont sur 16 bits, alors le résultat de buf[0]<< 8 peut n'être pas représentable par un int (pour buf[0] >127) et dans ce cas le comportement est indéfini .

    Manipuler les bits impose de connaitre la représentation interne des nombres signés : complément à 2 ou autre chose (pas fréquent), ordre des bytes msb->lsb ou lsb->msb (les deux sont fréquents) ou autre (rare). Même en se limitant aux cas fréquents, on a deux options pour cette représentation : complément à 2 + msb->lsb et complément à 2 + lsb->msb . On a donc intérêt à chercher une méthode plus abstraite indépendante de la représentation interne à obtenir.

    Si buf[] est censé représenter un nombre entier en complément à 2 avec buf[0] comme poids fort, on peut faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    val = buf[1] +  (buf[0]>127 ? (buf[0]-256)*256 : buf[0]*256);
    qui donnera dans l'exemple val = -23325;

    Le résultat est alors indépendant de la représentation interne à la machine des nombres signés (c'est une méthode calculant la valeur d'un nombre dont on connait la représentation en complément à 2) et doit marcher si les int ont 16 bits minimum (les termes de l'expression tenant sur 16 bits signés).

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 855
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 855
    Par défaut
    merci pour les explications

    Par contre je n'ai pas compris où était le problème pour ça :
    Si les int sont sur 16 bits, alors le résultat de buf[0]<< 8 peut n'être pas représentable par un int (pour buf[0] >127) et dans ce cas le comportement est indéfini .
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    unsigned char buf[2]
    signed int val;
    // val = -22015
    buf[0] = 0b10101010;
    buf[1] = 0b00000001;
    val = (buf[0] << 8) + buf[1];
    si on décompose, ça donne (si on est en complément A2)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    1- buf[0] est automatiquement casté en int 16 bits => 0b00000000 10101010;
    2- le décalage de bit est effectué => 0b10101010 00000000;
    3- buf[1] est automatiquement casté en int 16 bits => 0b00000000 00000001;
    4- les valeurs sont additionnées 0b10101010 00000000 + 0b00000000 00000001 = 0b10101010 00000001 = -22015
    => je ne vois pas ou il y a de risque de problème

    sinon, est-ce que vous connaissez un bon tuto complet qui explique comment sont évaluées/castées les expressions en C ?

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

Discussions similaires

  1. [CASTS]problème de cast de Time
    Par DeVoN dans le forum Langage
    Réponses: 7
    Dernier message: 22/02/2006, 17h24
  2. [JDBC Driver][JSTL] Problème de cast de données
    Par GyLes dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 27/09/2005, 10h00
  3. problème de cast!
    Par LaseLiep dans le forum Langage
    Réponses: 3
    Dernier message: 03/06/2005, 09h30
  4. Problème de cast/serialization/externalization ?
    Par Linlin dans le forum CORBA
    Réponses: 1
    Dernier message: 06/12/2004, 16h46
  5. [C#] Problème de casting de @IDENTITY
    Par bilb0t dans le forum Accès aux données
    Réponses: 7
    Dernier message: 03/09/2004, 09h42

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