2009-02-25 8 views
7

J'utilise des champs de bits pour accéder facilement à une librairie flottante que j'essaie de créer pour un microcontrôleur sans FPU.Quelle est la bonne façon d'utiliser les champs de bits en C?

Le problème est que je ne peux pas sembler le faire fonctionner avec bitfields. Jetez un oeil:

typedef struct 
{ 
    union{ 
    unsigned long mantissa: 23; 
    unsigned long exponent: 8; 
    unsigned long sign: 1; 
    float all; 

     }; 

}_float __attribute__((__packed__)); 

Le problème est que lorsque je tente d'accéder ou de changer quoi que ce soit il considère les bitfields comme 1,8,23 bits à partir de la fin respectivement. Alors qu'il devrait être 23 bits de la fin, puis 8 bits, puis le dernier bit. Sauf si j'ai totalement mal compris l'utilisation de bitfields. Je pensais que l'utilisation emballé résoudrait le problème, mais comme vous pouvez le voir n'a pas.

Toute aide serait vraiment appréciée. J'ai été conduit à ce site tout en googlant plus d'une fois donc j'ai de grands espoirs.

+1

La façon correcte d'utiliser les champs de bits est de ne pas utiliser les champs de bits. –

Répondre

17

Vous pourriez manquer une structure dans votre union.

typedef struct 
{ 
    union{ 
     struct { 
      unsigned long mantissa: 23; 
      unsigned long exponent: 8; 
      unsigned long sign: 1; 
     } float_parts; 
     float all; 
    }; 
}_float __attribute__((__packed__)); 

Notez que l'ordre de la mantisse/exposant et du signe dépend de l'endianess du cpu.

+0

Merci de votre contribution, mais pourquoi ajouter une structure au sein du syndicat? J'ai fait l'union des parties du flotteur avec le flotteur pour m'assurer que chaque bitfield correspond à la partie appropriée du flotteur. Est-ce pas assez? –

+1

une union fera tous ses membres partagent la même mémoire. Je ne pense pas que l'utilisation de bitfields changera ce comportement, donc tous vos champs de bits commencent au bit 0, tout comme le float "tout". Les mettre dans une structure rend l'agencé séquentiellement. – rmeador

+0

Vous aviez absolument raison! C'est ce qui était nécessaire. Je blâme ma compréhension de l'union alors :). Merci mon ami, maintenant je peux accéder à n'importe quelle partie de mon char à volonté. –

0

Le problème est que c'est une union. Cela devrait être 'struct'.

0

Si vous êtes sur une plate-forme glibc, vous pouvez consulter le fichier d'en-tête ieee754.h. Il prend soin des choses de l'endianess. Si ce n'est pas le cas, il vaut probablement la peine d'y jeter un coup d'œil.

Questions connexes