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 :

probleme de casting


Sujet :

C

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 14
    Points : 2
    Points
    2
    Par défaut probleme de casting
    Bonjour,

    Dans le cadre d'une appli pour un µC je voulais savoir si cela est acceptable en C:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    char moyenne;
    int result, a, b, c;
    long d;
     
     
    result = (a / (float) b) * 100;
     
    moyenne = (char)( (d + result) / (float)c);
    Le resultat de la division etant dans mon cas toujours inferieure à 100 je souhaite affecter à moyenne une variable de type char, puisqu'ensuite je stocke cette moyenne en E²prom.

    Mon raisonnement est le suivant avec un exemple concret:

    a=20 -> a=20.0
    b=50 -> b=50.0

    result = (20.0/50.0) * 100.0 = 40.0

    Comme result est déclaré en int => result = 40

    Puis:

    d = 78000
    result = 40
    c = 5000

    donc moyenne = (78000.0+40.0) / 5000.0 = 15.608

    Si je fais un cast de type char sur le calcul je devrais avoir au final moyenne = 15 ?

    Est-ce correct ce type de casting ou pas ?

    Merci d'avance pour vos conseils.

  2. #2
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    947
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

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

    Informations forums :
    Inscription : Mars 2006
    Messages : 947
    Points : 1 351
    Points
    1 351
    Par défaut
    Salut,

    Si tu travailles avec un µC, je te conseille de poser dès le départ quelques typedef (uint16, sint16 etc...) avec les assertions qui vont bien pour vérifier les tailles, parce que la taille de int dépend de l'architecture du µC (8 16, 32)...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    result = (a / (float) b) * 100;
    le problème, c'est que ni result ni a ni 100 ne sont des floats. J'aurais bien écrit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    result = ((float)a / (float) b) * 100.0;
    Mais comme résult n'est de toute façon pas un float...

  3. #3
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    Si je fais un cast de type char sur le calcul je devrais avoir au final moyenne = 15 ?
    Oui. tant que la partie entière de (d + result) / (float)c tient dans un char, c'est bon. Sinon le comportement est indéfini.
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  4. #4
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 14
    Points : 2
    Points
    2
    Par défaut
    Merci pour ton intérêt à mon problème,

    dans mon cas sur mon compilo:

    char ou short -> 1 octet
    int -> 2 octets
    long -> 4 octets


    result n'est pas un float mais je suppose que ce qu'il y a après la virgule disparait d'office, seule la partie entière est récupérée par moyenne qui est déclarée en int.
    Ou me gourge...

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 14
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par diogene Voir le message
    Oui. tant que la partie entière de (d + result) / (float)c tient dans un char, c'est bon. Sinon le comportement est indéfini.
    Merci bien, je vais tester ça.

    Juste une petite précision, le casting est donc appliqué après le calcul fait dans la parenthèse ?
    On calcule puis on cast le tout, c'est bien ça ?

  6. #6
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    947
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

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

    Informations forums :
    Inscription : Mars 2006
    Messages : 947
    Points : 1 351
    Points
    1 351
    Par défaut
    Citation Envoyé par Lynx91 Voir le message
    result n'est pas un float mais je suppose que ce qu'il y a après la virgule disparait d'office, seule la partie entière est récupérée par moyenne qui est déclarée en int.
    C'est juste. Ton cast implicite pourrait être un peu plus juste ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    result = ((float)a / (float) b) * 100.0 + 0.5;
    Mais je pense que pour la compréhension, il serait mieux d'écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    result = int(((float)a / (float) b) * 100.0 + 0.5);
    Pour l'assembleur obtenu, ça ne fera aucune différence.

  7. #7
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 14
    Points : 2
    Points
    2
    Par défaut
    Ah oui bien vu le coup d'ajouter 0.5, j'avais pas vu ça.

    Merci encore à vous deux.

  8. #8
    Expert confirmé Avatar de fregolo52
    Homme Profil pro
    Développeur C
    Inscrit en
    Août 2004
    Messages
    2 364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Août 2004
    Messages : 2 364
    Points : 5 378
    Points
    5 378
    Par défaut
    Citation Envoyé par Lynx91 Voir le message
    donc moyenne = (78000.0+40.0) / 5000.0 = 15.608

    Si je fais un cast de type char sur le calcul je devrais avoir au final moyenne = 15 ?
    Je n'ai pas tout compris ! Tu veux quoi comme résultat ? 15 ou 16 ? Si c'est 16, le dernier message pfeuh me semble être la meilleure solution.

  9. #9
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 14
    Points : 2
    Points
    2
    Par défaut
    Oui arrondi au plus proche c'est mieux.

  10. #10
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    Juste une petite précision, le casting est donc appliqué après le calcul fait dans la parenthèse ?
    On calcule puis on cast le tout, c'est bien ça ?
    Oui, et le cast final est inutile : le compilateur constatant qu'il doit mettre le résultat dans un int fera le transtypage automatiquement. C'est inutile d'alourdir des formules par des cast et des parenthèsages inutiles.

    Ah oui bien vu le coup d'ajouter 0.5, j'avais pas vu ça.
    Attention, cette méthode d'arrondi n'est valable que pour un résultat positif
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  11. #11
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 14
    Points : 2
    Points
    2
    Par défaut
    Attention, cette méthode d'arrondi n'est valable que pour un résultat positif
    C'est mon cas ici en fait.
    J'essaye tout ça ce soir.

  12. #12
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 14
    Points : 2
    Points
    2
    Par défaut
    Bon c'est ok, ça tourne.

    Une dernière question:

    Je stocke un long en E²PROM, donc je "découpe" le long ainsi pour pouvoir le ranger dans la mémoire:

    unsigned long d;
    char d1, d2, d3, d4;

    d1 = char(d >> 24); // on recupere le MSB (octet 4)
    d2 = char(d >> 16); // octet 3
    d3 = char(d >> 8); // octet 2
    d4 = char(d); // octet 1 (LSB)
    En gros la question est de savoir si le simple fait de caster en char suffit à ne conserver que les bits utiles dans chacun des octets de stockage qui m'intéressent, un coup de rabot en quelque sorte.
    A moins qu'il y ait un truc plus subtil à faire dans ce cas là.

  13. #13
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    947
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

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

    Informations forums :
    Inscription : Mars 2006
    Messages : 947
    Points : 1 351
    Points
    1 351
    Par défaut
    Citation Envoyé par Lynx91 Voir le message
    savoir si le simple fait de caster en char suffit à ne conserver que les bits utiles dans chacun des octets de stockage
    A priori oui, si tes chars font bien 8 bits. Ce qui est généralement le cas, a fortiori sur un µC.

  14. #14
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 14
    Points : 2
    Points
    2
    Par défaut
    Ok merci pour cette confirmation.

Discussions similaires

  1. Probleme de cast de string en int
    Par Oberown dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 26/04/2006, 11h48
  2. Réponses: 12
    Dernier message: 25/07/2005, 14h49
  3. [VB.NET][dataset][datagrid] probleme de Cast
    Par graphicsxp dans le forum Windows Forms
    Réponses: 3
    Dernier message: 05/05/2005, 14h18
  4. Probleme de cast de parametres
    Par John Fullspeed dans le forum Langage
    Réponses: 3
    Dernier message: 14/10/2004, 08h43
  5. probleme de cast
    Par gaut dans le forum C++
    Réponses: 9
    Dernier message: 06/08/2004, 18h43

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