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 :

Donnees binaire et operations


Sujet :

C

  1. #1
    Nouveau membre du Club
    Inscrit en
    Avril 2007
    Messages
    75
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 75
    Points : 38
    Points
    38
    Par défaut Donnees binaire et operations
    Bonjour a vous,

    j'ai un vrai probleme de comprehension concernant les operations binaires, je vous explique mon probleme :

    J'ai 2 fichiers binaires en lecture.
    chaque data est sur 16 bits

    Fichier1 (dans le tableau float[]) :
    0001
    FFFB
    ...

    Fichier2 (dans le tableau entier[]):
    00FE
    etc ...

    La valeur du fichier 1 est comprise entre -1 et 1 donc par exemple pour le fichier 1, il y a les valeurs 1 et -5 ( signe ), en realite les valeurs sont : 0,1 et -0,5.

    Les valeurs du fichier 2 sont juste des entiers sur 16 bits.

    _____________

    J'ai donc stocke mes valeurs dans 2 tableaux de short int.
    le calcul se fera dans un long ou n'importe quoi de signe sur 32 bits (precision) que je devrais ensuite ecrire sous un format 16 bits en sortie et en binaire egalement.

    le probleme :

    je dois donc multiplier entier[i] avec float[i] ( je comprends que les noms entier et float peuvent preter a confusion, c'est juste pour me rapeler ce que represente les donnees lues et toutes enregistres dans un tableau de type short int sur 16 bits)

    apres la multiplication je dois donc diviser le resultat par le nombre qui va bien :

    Exemple : ( dans l'ordre entier * float )
    5 * 2 = 10 et ensuite il faut que je divise par 10 car en realite c'est 5 * 0.2
    10 * -8912 = -89120 et il faut ensuite diviser par 10000 ...

    Bon alors la au niveau codage je suis parti sur l'idee de faire une longue division par 10 jusqu'a avoir un reste entier de 0 et diviser par 10 fois le nombre de division faite. Ca a l'air bien lourd et je me demande si il n'y a pas de solutions plus simple.

    Probleme 2 :
    Comment passer d'un 32 bits a un 16 bits en gardant seulement les bits de poids fort ....

    Merci d'avance, ce probleme est ridicule a l'ecrit mais je n'ai aucune idee de l'implementation en faite ...

    Cdt,
    Kichon.

  2. #2
    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 babykichon Voir le message
    Probleme 2 :
    Comment passer d'un 32 bits a un 16 bits en gardant seulement les bits de poids fort ....
    Si j'ai bien compris :
    int16 = int32 >> 16; // tu fais un décalage de 16 bits vers la droite

  3. #3
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    946
    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 : 946
    Points : 1 351
    Points
    1 351
    Par défaut
    Salut,

    Pour le problème 1 , je n'ai pas vraiment compris la question. Pour le 2, ça va mieux. Les typedef sont là pour la compréhension, et les assert pour être sur que tu es bien sur un système 32 bits. Il faut changer les typedef sinon. Tu peux bien sûr simplifier ce code.

    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
    #include <stdio.h>
    #include <assert.h>
     
    typedef short unsigned int uint16;
    typedef unsigned int uint32;
     
    uint16 from32To16(uint32 data)
    {
        return data >> 16;
    }
     
    int main(int argc, char **argv)
    {
        assert(sizeof(uint16) == 2);
        assert(sizeof(uint32) == 4);
        printf("%x -> %x\n", 0xcafedeca, from32To16(0xcafedeca));
        return 0;
    }
    A+

    Pfeuh

  4. #4
    Nouveau membre du Club
    Inscrit en
    Avril 2007
    Messages
    75
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 75
    Points : 38
    Points
    38
    Par défaut
    Merci de vos reponses mais j'avais pas bien compris.

    En faite les donnees sont comprises entre -1 et 1, donc les valeurs lues sous 16 bits, provenant de mes 2 fichiers d'entrees, doivent etre diviser par 2^15 pour les remettre en float. Ensuite le calcul x * h est fait en float et je dois remultiplier le resultat par 2^31 pour le reconvertir en entier. Le soucis etant de garder juste les 16 bits de poids fort.

    Pour le moment reecris le resultat du calcul (apres le *2^31) provenant d'une variable type double, dans un short int.
    Je n'ai pas encore valider mon process mais pour le moment j'ai en hexa 16 bits sur mon fichier de sortie la meme valeur que celle trouve en entier naturel. le probleme etant que je n'ai pas teste les points critiques, c'est a dire si le resultat depasse la capacite du short int ... il faudra tronquer le resultat mais ne garder que les poids forts, sans introduire les 1 par la gauche si je fais un decallage sur une valeur signée ...
    Le decallage ne peut pas marcher a mon avis car les valeurs sont signe donc ca va juste me remplir de FFF sur la gauche.

    J'espere que c'est pas trop du charabia ... je reviendrais avec le probleme concret et le code correspondant, merci de votre aide

  5. #5
    Nouveau membre du Club
    Inscrit en
    Avril 2007
    Messages
    75
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 75
    Points : 38
    Points
    38
    Par défaut
    Bonjour tout le monde,
    Me revoila avec mon petit probleme

    Le process etant code, j'ai toujours mon soucis sur la sortie.
    Le calcul de la sortie est fait dans un double et les calculs sont fait en format float.

    Donc : En sortie j'ai un Yn ( nom de la sortie ) code sur 64 bits.
    Objectif : Passe au format int et sur 16 bits signe.

    Premiere etape : Multiplie ma sortie par 2^31 pour repasser au format integer
    (Ici, lorsque je parle de format Int ou Float, cela correspond au format utilise dans matlab. Cela change donc le range de la variable. Par exemple, pour le format float, la valeur est comprise entre -1 et 1)

    Deuxieme etape : Recuperer les 16 bits MSP (Most significant Part) de mon resultat et mettre tout ca dans un short int ( 16 bits ), pour ensuite ecrire mon resultat en hexa dans un fichier de sortie.

    Probleme :
    J'ai du mal a faire ce convert 64 to 16 en signe .... les decallages font entrer des 1 par la gauche a cause du bit de signe ...

    Je me documente a l'heure actuelle mais si quelqu'un a une idee, comme d'habitude je suis preneur.

    Merci d'avance !!

  6. #6
    Nouveau membre du Club
    Inscrit en
    Avril 2007
    Messages
    75
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 75
    Points : 38
    Points
    38
    Par défaut
    Je vais mettre un bout de code ca sera plus parlant en faite :

    J'ai voulu repartir de l'exemple que l'on ma envoyé quelques postes au dessus.

    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
     
    #include <stdio.h>
    #include <assert.h>
     
    short int from64To16(double data)
    {      
        return data >> 48;
    }
     
    int main(int argc, char **argv)
    {
        double y = 0xcafedecacafedeca;
        printf("%x -> %x \n", y, from64To16(y));    
     
        return 0;
    }
    J'aimerai récupérer pour cet exemple
    y(16 bits) = cafe

    Bon, bien sur ca ne compile meme pas T_T


    EDIT :
    Ou alors plutot que passer par un decallage, juste diviser mon Yn par 2^48.
    Sur le papier ca revient au meme mais bon une fois code le resultat est peu probant haha ...

  7. #7
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    946
    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 : 946
    Points : 1 351
    Points
    1 351
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    short int from64To16(double data)
    {      
        return data >> 48;
    }
    C'et normal que ça ne compile pas. data est un double, c'est à dire un flottant sur 64 bits. C'est à dire que tu essaies de faire une opération binaire (décalage) sur quelque chose qui n'est pas binaire.

  8. #8
    Nouveau membre du Club
    Inscrit en
    Avril 2007
    Messages
    75
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 75
    Points : 38
    Points
    38
    Par défaut
    Merci de ta reponse, mais donc j'ai toujours du mal a voir comment realiser la deuxieme etape.
    Car diviser mon resultat par 2^48, j'arrive aussi a une valeur fausse ...

    Deuxieme etape : Recuperer les 16 bits MSP (Most significant Part) de mon resultat et mettre tout ca dans un short int ( 16 bits ), pour ensuite ecrire mon resultat en hexa dans un fichier de sortie.

  9. #9
    Nouveau membre du Club
    Inscrit en
    Avril 2007
    Messages
    75
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 75
    Points : 38
    Points
    38
    Par défaut
    Probleme regle et plutot stupide au final.
    Voici la solution toute simple, ca pourra peut etre servir a quelqu'un



    double Y; // Y = sortie d'un process float
    short int X;

    X = 2^15 * Y;
    //remet la valeur au format int ( 2^15 suffit car short int sur 16bits)

    _____________________

    Voila, merci pour votre aide, ca m'a mit sur la piste
    Sinon juste une question, comment verifier simplement sur combien de bits est un double, ou un short int selon le compilateur.




    EDIT pour le reponse en dessous :

    Oops, excuse moi je suis un peu a l'ouest
    Merci

  10. #10
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    946
    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 : 946
    Points : 1 351
    Points
    1 351
    Par défaut
    Citation Envoyé par babykichon Voir le message
    comment verifier simplement sur combien de bits est un double, ou un short int selon le compilateur.
    Ca, je te l'avais déjà donné...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #include <stdio.h>
    #include <assert.h>
    int main(int argc, char **argv)
    {
        assert(sizeof(double) == 8);
        assert(sizeof(short int) == 2);
        return 0;
    }

  11. #11
    Nouveau membre du Club
    Inscrit en
    Avril 2007
    Messages
    75
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 75
    Points : 38
    Points
    38
    Par défaut
    Petite question histoire de peaufiner tout ca

    Forcement vu le code j'ai un warning qui sort sur cette ligne :

    s16_result = Yn[0] * (pow(2,15)); //Warning C4244 Level 2

    Bon il y a peut etre une solution super propre pour prevenir le compilateur que je veux perdre ma precision.
    J'ai tente d'ecrire explicitement le cast mais apparement il s'en tape royalement.
    Il y a une facon propre d'ecrire ca ? Je n'aime pas les warnings dans mon code, et je n'aime pas la solution "microsoft" qui consiste a masquer le warning, en changeant le level de warning dans les options du compilateur ( joke )

  12. #12
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    946
    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 : 946
    Points : 1 351
    Points
    1 351
    Par défaut
    un bête cast, peut-être?

    s16_result = (uint16)(Yn[0] * (pow(2,15)));

  13. #13
    Nouveau membre du Club
    Inscrit en
    Avril 2007
    Messages
    75
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 75
    Points : 38
    Points
    38
    Par défaut


    Merci, j'etais parti un peu trop loin en effet ...

    Pourquoi toujours essayer le chemin le plus long T___T"

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

Discussions similaires

  1. [XML] Insérer des données binaires ?
    Par Matthieu Brucher dans le forum XML/XSL et SOAP
    Réponses: 8
    Dernier message: 11/12/2008, 14h27
  2. Operation Logique Binaire
    Par gilles06 dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 10/03/2008, 17h20
  3. [JDBC]insertion donnée binaire dans bd
    Par MrX dans le forum JDBC
    Réponses: 1
    Dernier message: 05/10/2005, 14h18
  4. Operations en binaire
    Par Freakazoid dans le forum C++
    Réponses: 4
    Dernier message: 07/08/2004, 09h09

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