Extraire les 16 premiers bits d'un float

Résolu/Fermé
maniqk - 23 juil. 2013 à 11:17
juliencolin54 Messages postés 217 Date d'inscription dimanche 22 juillet 2012 Statut Membre Dernière intervention 1 octobre 2013 - 24 juil. 2013 à 09:29
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
A voir également:

13 réponses

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
juliencolin54 Messages postés 217 Date d'inscription dimanche 22 juillet 2012 Statut Membre Dernière intervention 1 octobre 2013 55
Modifié par juliencolin54 le 24/07/2013 à 09:29
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
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
juliencolin54 Messages postés 217 Date d'inscription dimanche 22 juillet 2012 Statut Membre Dernière intervention 1 octobre 2013 55
23 juil. 2013 à 11:35
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
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

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
juliencolin54 Messages postés 217 Date d'inscription dimanche 22 juillet 2012 Statut Membre Dernière intervention 1 octobre 2013 55
23 juil. 2013 à 11:39
N'hésite pas si t'as des questions sur la manipulation des masques,

Cdlt.
0
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
comment sont stockés les nombres flottants: http://fr.wikipedia.org/wiki/IEEE_754
bon courage pour faire ton masque la dessus :)
0
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
juliencolin54 Messages postés 217 Date d'inscription dimanche 22 juillet 2012 Statut Membre Dernière intervention 1 octobre 2013 55
23 juil. 2013 à 11:53
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
Tu cherches à faire une représentation des nombres imaginaires maniqk ?
0
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
juliencolin54 Messages postés 217 Date d'inscription dimanche 22 juillet 2012 Statut Membre Dernière intervention 1 octobre 2013 55
23 juil. 2013 à 15:54
@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
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
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
juliencolin54 Messages postés 217 Date d'inscription dimanche 22 juillet 2012 Statut Membre Dernière intervention 1 octobre 2013 55
23 juil. 2013 à 12:39
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
Euh, j'ai fait float nombre = 3.5; puis nombre = nombre & 0xA0 mais il me dit "expression must have integral type" :/
0
juliencolin54 Messages postés 217 Date d'inscription dimanche 22 juillet 2012 Statut Membre Dernière intervention 1 octobre 2013 55
23 juil. 2013 à 14:43
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
juliencolin54 Messages postés 217 Date d'inscription dimanche 22 juillet 2012 Statut Membre Dernière intervention 1 octobre 2013 55
23 juil. 2013 à 14:45
Je ne suis pas sur mon pc donc pour l'instant je ne peux pas tester de code , sorry :)
0