2009-02-25 9 views
7

Sto usando bitfield per ottenere un facile accesso su una libreria float che sto cercando di creare per un microcontrollore senza FPU.Qual è il modo corretto di utilizzare i bitfield in C?

Il problema è che non riesco a farlo funzionare con bitfield. Date un'occhiata:

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

     }; 

}_float __attribute__((__packed__)); 

Il problema è che quando provo ad accedere o cambiare qualcosa che considera i campi di bit come 1,8,23 bit dalla fine, rispettivamente. Mentre dovrebbe essere 23 bit dalla fine, quindi 8 bit e poi l'ultimo bit. A meno che non abbia totalmente frainteso l'uso dei bitfield. Ho pensato che l'utilizzo di impacchettato avrebbe risolto il problema ma come puoi vedere non è stato così.

Qualsiasi aiuto sarebbe molto apprezzato. Sono stato condotto a questo sito mentre facevo ricerche su Google più di una volta quindi ho grandi speranze.

+1

Il modo corretto di utilizzare i bitfield è di non utilizzare bitfield. –

risposta

17

Potrebbe mancare una struttura all'interno dell'unione.

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

Si noti che l'ordine di mantissa/esponente e segno dipende da un endianess della CPU.

+0

Grazie per il tuo contributo, ma perché aggiungere una struttura all'interno dell'unione? Ho fatto l'unione delle parti del galleggiante con il galleggiante per assicurarmi che ogni bitfield corrisponda alla parte appropriata del galleggiante. Non è abbastanza? –

+1

un sindacato farà sì che TUTTI i suoi membri condividano la stessa memoria. Non penso che l'uso di bitfield cambierà questo comportamento, quindi tutti i tuoi bitfield partono dal bit 0, proprio come fa il float "all". Mettendoli in una struttura rende la disposizione in sequenza. – rmeador

+0

Avevi assolutamente ragione! Questo è ciò che era necessario. Dò la colpa alla mia comprensione dell'unione quindi :). Grazie amico, ora sono in grado di accedere a qualsiasi parte del mio galleggiante a volontà. –

0

Il problema è che è un'unione. Dovrebbe essere 'struct'.

0

Se sei su una piattaforma glibc puoi dare un'occhiata al file di intestazione ieee754.h. Si occupa delle cose di endianess. Se no, probabilmente vale ancora la pena dargli un'occhiata.

Problemi correlati