Extraire les 16 premiers bits d'un float

Résolu
maniqk -  
juliencolin54 Messages postés 238 Statut Membre -
Bonjour,

Je souhaiterais extraire les 16 premiers bits d'un float (codé sur 32 bits donc).
La précision du nombre sera moindre mais cela me suffit pour le moment.
Quelqu'un pourrait il m'aider ? Je ne connais pas bien la manipulation des bits..

Merci d'avance,
maniqk

13 réponses

  1. maniqk
     
    Et bonjour à tous les deux !

    Merci de votre aide... Mais j'ai vu avec le forum de l'entreprise qui produit la carte sur laquelle je travaille, et... Ce n'est pas possible d'utiliser ma fonction avec des floats ! J'aurais pu chercher longtemps...

    A la prochaine !
    1
    1. juliencolin54 Messages postés 238 Statut Membre 55
       
      Bonjour,

      On aura essayé !
      J'ai quand même fait un code qui affiche tout les bit d'un double, si ça peut-être utile, n'hésite pas.

      Cdlt.
      0
  2. lefoudelitalie
     
    Bonjour
    Je ne comprend pas bien le but de ta manipulation car un float est le plus petit type standart pour stocker les nombre a virgule, tu n auras aucun gain de place à moins de créer ton type.

    Si tu souhaites tout de même extraire les 16 premier bits je te conseil dans un premier temps de regarder comment sont stockés les nombres à virgule dans la mémoire puis de faire un ton chiffre & masque. Le masque te premettant de selectionner les bits que tu souhaites garder
    0
  3. juliencolin54 Messages postés 238 Statut Membre 55
     
    Peut-être que cela t'aidera :

    42 (10)
    <=>
    101010 (2)

    Pour extraire les bits un à un tu peux commencer par appliquer un masque binaire à ton nombre.
    masque pour le 1er bit :
    100000
    masque pour le 2e bit :
    010000
    masque pour le 3e bit :
    001000
    masque pour le 4e bit :
    000100
    (...)
    0
  4. maniqk
     
    Bonjour et merci de ta réponse !

    En fait je vais appeler mes nombres dans une fonction qui prend en entrée des nombres codés sur 64 bits.

    Ces 64 bits représentent 2 nombres de 32 bits.
    Et chaque nombre de 32 bits doit contenir dans les 16 MSB la partie réelle de mon nombre, et les 16 LSB la partie imaginaire.

    J'ai fait cette manipulation avec des int, c'était plus simple puisque je ne gérais pas non plus des très grands entiers (donc en fait je saturais mon nombre en des valeurs de 16 bits). Avec des floats c'est une autre affaire.

    J'allais demander des infos sur le masque mais juliencolin a répondu à mes questions je crois, donc merci à tous les deux !
    0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. juliencolin54 Messages postés 238 Statut Membre 55
     
    N'hésite pas si t'as des questions sur la manipulation des masques,

    Cdlt.
    0
  7. maniqk
     
    En fait je ne comprends pas trop comment fonctionne le masque.

    Si j'ai un float a = 3.5; (0/10000000/11000000000000000000000 en binaire si je ne me trompe pas)

    Que me renvoie "a & 100000" ? Ca me renvoie 0 du coup ?
    0
  8. lefoudelitalie
     
    comment sont stockés les nombres flottants: http://fr.wikipedia.org/wiki/IEEE_754
    bon courage pour faire ton masque la dessus :)
    0
  9. maniqk
     
    Oui le foudelitalie, c'est pour ça que j'avais du mal à faire ce que je veux faire ^^
    Mais au final si je garde les 16 premiers je perdrai en précision mais je garderai une valeur assez approchée de mon nombre, enfin je crois.

    Je crois aussi que je cherche pour rien, parce que même si je garde mes 16 premiers bits, une fois packé avec mes autres valeurs, la fonction va probablement interpréter mon nombre en tant que int et ne "comprendra" pas le float que je veux réellement mettre en entrée :/ Hmm j'ai encore du boulot ^^
    0
  10. juliencolin54 Messages postés 238 Statut Membre 55
     
    Je n'ai aucune idée de comment se représente ton float en mémoire mais,

    imaginons qu'il se représente de cette manière la :

    1000110011100111

    La masque à appliquer pour avoir le Nième bit en partant de la droite (si je ne me trompe pas) est 2^(N-1) (base 10)

    Pour avoir le bit tout à gauche ce serait donc

    3.5 & 2^(16 -1)
    = 3.5 & 2^15
    = 1000110011100111 & 1000000000000000
    = resultat > à 0 donc 1
    0
  11. lefoudelitalie
     
    Tu cherches à faire une représentation des nombres imaginaires maniqk ?
    0
  12. maniqk
     
    Non, pas du tout lefou ^^

    C'est pour faire la multiplication d'un vecteur 1x2 par une matrice 2x2.

    J'ai une fonction qui fait ça (ce n'est pas moi qui l'est faite, elle est implantée dans une carte). Pour être exact elle prend en entrée un long long et un __x128_t.
    Le long long correspondant donc à 2 nombres, dont les 16 MSB sont la partie réelle, et les 16 LSB la partie imaginaire comme je l'ai dit précédemment.
    Pareil pour le __x128_t sauf que 4 nombres sont représentés dans une seule variable.

    Pour juliencolin, quelle est l'utilité de savoir que le résultat est supérieur à 0 ?
    Et si je récupère mes 16 bits de cette façon, je peux les remettre bout à bout dans une autre variable du coup ?
    0
  13. juliencolin54 Messages postés 238 Statut Membre 55
     
    @lefoudelitalie, "c est 0XFFFF0000 pour avoir un masque sur 32 bit"
    Je vois pas très bien ce que tu veux dire par là
    0
  14. lefoudelitalie
     
    nombre = nombre & 0xA0 //on récupère les 16 premiers bit

    nombre2 =nombre2 & 0xA0 //on récupère les 16 premiers bit

    nombre2 =nombre2>>16 //on decale vers la droite de 16 le nombre2

    nombre | nombre2 // tu colles tes deux nombres
    -1
    1. lefoudelitalie
       
      vérifie quand même la cohérence de tes chiffres à virgule savoir si ils se rapprochent réellent de la vrai valeur flotante
      0
    2. juliencolin54 Messages postés 238 Statut Membre 55
       
      En fait si c'est supérieur à zéro c'est que le bit est à 1 sinon il est à 0.

      Par exemple :
      42 & 2 (10)
      = 101010 & 000010 (2)
      = 000010 (2)
      = 2 (10)

      On obtient bien le bit à un sauf que l'on ne change pas son rang...
      Alors le résultat est 2 (10) et 1 (10).
      0
    3. maniqk
       
      Euh, j'ai fait float nombre = 3.5; puis nombre = nombre & 0xA0 mais il me dit "expression must have integral type" :/
      0
    4. juliencolin54 Messages postés 238 Statut Membre 55
       
      Peut-être si tu le cast en int ... Mais vu que la taille en mémoire est plus petite , ça va le tronquer !

      Par contre tu pourrais peut-être caster en char * pour qu'il soit découpé en groupes distincts d'octets sur lesquels tu pourrais appliquer ton masque binaire ?

      Si et seulement si le cast d'un double en char * à le même effet le le cast d'un int dans un char *.
      C'est à dire :
      int nb = 5737796 (10) = 1010111 10001101 01000100 (2)
      char *nb_cast:
      
      nb_cast = (char *)&nb;


      On à en résultat :
      nb_cast[0] == 01000100
      nb_cast[1] == 10001101
      nb_cast[2] == 1010111
      nb_cast[3] == 0

      Ou l'inverse suivant ton endianess.
      0
    5. juliencolin54 Messages postés 238 Statut Membre 55
       
      Je ne suis pas sur mon pc donc pour l'instant je ne peux pas tester de code , sorry :)
      0