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 :

donnée 12bit dans char => integer


Sujet :

C

  1. #1
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    29
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 29
    Par défaut donnée 12bit dans char => integer
    Bonjour,

    Avant de commencer, je tiens à préciser que mon objectif n’est pas de convertir la string « 34 » vers l’integer 34 et que les nombreux sujets sur le forum ne traitent donc pas mon problème ( juste pour éviter quelques baffes )
    Voilà donc : Je récupère une chaine de 6 char (donc des données sur 8 bits) dans laquelle se trouve en fait 4 nombres codés sur 12 bits. Si vous faites le calcul, on a bien un total de 48 bits (soit divisé par 8, 6 char de 8 bits). Mon objectif est simplement de placer le plus efficacement possible chacun des 4 nombres dans un integer.

    J’espère que mon explication est assez clair. Je pense que je dois jouer avec les décalages, mais je ne suis pas bien certain de comment et surtout, il existe peut-être une fonction magique.

    Bel’

  2. #2
    Membre très actif

    Homme Profil pro
    Collégien
    Inscrit en
    Juillet 2010
    Messages
    582
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Juillet 2010
    Messages : 582
    Par défaut
    Salut,

    un truc du genre?

    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    typedef struct
    {
        uint16_t    msb;
        uint32_t    lsb;
    } _48bits_t
     
     
    _48bits_t * tab2struct(_48bits_t * this,const char tab[6])
    {
        if(this && tab)
        {
            this->msb = (((tab[0]<<4) | (tab[1]>>4))<<12)           |   /*12bits*/
                        (tab[1]&0xF);                                   /*4bits*/
            this->lsb = (tab[2]<<24)                                |   /* 8bits*/
                        (((tab[3]<<8) | ((tab[4]&0xF0)>>4))<<12)    |   /* 12bits*/
                        ((((tab[4]&0xF)<<8) | (tab[5])));            /* 12bits*/
        }
        return this;
    }
     
    char * struct2tab(const _48bits_t * this,char tab[6])
    {
        if(this && tab)
        {
            tab[0]  = this->msb>>8;
            tab[1]  = this->msb&0xFF;
            tab[2]  = this->lsb>>24;
            tab[3]  = (this->lsb>>16)&0xFF;
            tab[4]  = (this->lsb>>8)&0xFF;
            tab[5]  = this->lsb&0xFF;
        }
        return this;
    }
    J'ai pas vérifié si c'est exactement ça.

  3. #3
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    29
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 29
    Par défaut C'est pur
    Bonjour,

    Merci pour cette réponse particulièrement rapide. En fait ce code sera ensuite envoyé vers un compilateur pour un micro-processeur (PIC pour ceux qui connaissent). Bref, je ne suis pas sûr mais il me semble que ton code est du C++, hors je ne peux utiliser que du C pur.


  4. #4
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    C'est bien du C. C'est juste l'usage de this comme argument qui doit te perturber.

  5. #5
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    29
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 29
    Par défaut
    Bonsoir,

    Oui, désolé, le this m'a induit en erreur. C'est nickel, merci à tous les deux.

    Bel'

  6. #6
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2007
    Messages
    697
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 697
    Par défaut
    Je me trombe peut-être mais pourquoi ne pas utiliser la fonction memcpy ?
    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
     
    _48bits_t * tab2struct(_48bits_t * this,const char tab[6])
    {
        if(this && tab)
        {
             memcpy(this, tab, 6);
        }
        return this;
    }
     
    char * struct2tab(const _48bits_t * this,char tab[6])
    {
        if(this && tab)
        {
           memcpy(tab, this, 6);
        }
        return this;
    }
    A part bien évidement si elle n'est pas disponible sur PIC.

    Qant-à la première fonction, je ne l'ai pas testé mais elle devrait lancer un "segmentation fault"
    Il faut plutôt écrire un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    this->msb = (tab[0] << 8) | tab[1];
    this->lsb = (tab[2]<<24) | (tab[3]<<16) | (tab[4]<<8) | tab[5];
    A noter qu'il faut vérifier que ton processeur ai des registres d'au moins 32 bits.


    Après il y a peut-être des problèmes d'endianness ou de padding dans la structure qui m'ont échappés.

  7. #7
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    29
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 29
    Par défaut
    Bonjour,

    En fait je n'ai pas repris tout le code de mith06, mais il m'a rappelé qu'il existe d'autre opérateurs que les +, - et * à savoir les fonctions logiques et les décalages. J’ai donc simplement déclaré 4 integer et j’ai fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Integer1 = buffer[0] ;
    Integer1 = Integer1<<4 +( buffer[1]>>4)&0x0F ;
    Integer2 = buffer[1]&0x0F ;
    Integer2 = Integer2<<8 + buffer[2] ;
    Integer3 = buffer[3] ;
    Integer3 = Integer3<<4 +( buffer[4]>>4)&0x0F ;
    Integer4 = buffer[4]&0x0F ;
    Integer4 = Integer4<<8 + buffer[5] ;
    Je devine cependant que c’est moins propre comme solution

    Bel’

  8. #8
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2007
    Messages
    697
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 697
    Par défaut
    Ça a le mérite de répondre à ton besoin. A pars peut-être pour le efficace (je ne sais pas comment se comportent les compilos dans l'embarqué).
    Quelques pistes :

    • tu utilises l'opérateur +, pourquoi pas | ? Dans ton cas ça fait la même chose, mais est-ce que ça le fait de la même manière ?
    • Dans certain cas tu passes par une variable intermédiaire. Un compilo pour PC la supprimerai mais dans ton cas ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Integer1 = buffer[0] << 4 | buffer[1] >> 4 & 0x0F; //opérateur >> (et<<) a une plus haute priorité que & et | 
    Integer2 = (buffer[1] & 0x0F) << 8 | buffer[2]; 
    Integer3 = buffer[3] << 4 | buffer[4] >> 4 & 0x0F; 
    Integer4 = (buffer[4] & 0x0F) << 8 | buffer[5];
    Bon ok, j'avoue le code est illisible^^

    • Sinon dans le genre plus efficace mais il faut tu ais les unions et les bitfields :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    union myUnion{
             struct {
                     int integer1: 12;
                     int integer2: 12;
                     int integer3: 12;
                     int integer4: 12;
             } dst;
             char src[6];
    } ;
    Mais bon je ne suis pas persuadé que ça soit très standard

  9. #9
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    29
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 29
    Par défaut
    Bonsoir,

    Merci atha2, je n'avais pas pensé à l'opérateur |. Du coup j'ai pris ton code (en plus il prend moins de place )

    Bel'

  10. #10
    Membre émérite Avatar de crocodilex
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    697
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 697
    Par défaut
    Citation Envoyé par atha2 Voir le message
    • Sinon dans le genre plus efficace mais il faut tu ais les unions et les bitfields :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    union myUnion{
             struct {
                     int integer1: 12;
                     int integer2: 12;
                     int integer3: 12;
                     int integer4: 12;
             } dst;
             char src[6];
    } ;
    Mais bon je ne suis pas persuadé que ça soit très standard
    Il faut se méfier des champs de bits. Ce n'est pas portable car dépendant de l'implémentation. Il n'est donc pas certain que ton exemple donne le même résultat que la première solution proposée.

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

Discussions similaires

  1. Récupération de données validées dans une pop-up
    Par hdd dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 01/12/2004, 16h47
  2. [POSTGRESQL]inserer des données distrinctes dans BD???
    Par perlgirl dans le forum Langage SQL
    Réponses: 2
    Dernier message: 12/11/2004, 16h10
  3. [JList] Lecture des données sauvegardées dans un fichier
    Par Myogtha dans le forum Composants
    Réponses: 7
    Dernier message: 10/06/2004, 21h05
  4. Réponses: 2
    Dernier message: 20/02/2004, 08h47
  5. problème xsl : inclure une donnée xml dans une balise html
    Par djodjo dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 03/01/2003, 09h24

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