2009-02-25 11 views
7

Ich verwende Bitfelder, um einen einfachen Zugriff auf eine Float-Bibliothek zu erhalten, die ich für einen Mikrocontroller ohne FPU erstellen möchte.Wie ist die korrekte Verwendung von Bitfeldern in C?

Das Problem ist, dass ich nicht scheinen kann, dass es mit Bitfeldern funktioniert. Werfen Sie einen Blick:

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

     }; 

}_float __attribute__((__packed__)); 

Das Problem ist, dass wenn ich versuche, etwas für den Zugriff auf oder ändern sie jeweils die Bitfelder als 1,8,23 Bits vom Ende hält. Während es 23 Bits vom Ende sein sollte, dann 8 Bits und dann das letzte Bit. Es sei denn, ich habe die Verwendung von Bitfeldern völlig missverstanden. Ich dachte, dass mit verpackt würde das Problem lösen, aber wie Sie sehen können, tat es nicht.

Jede Hilfe würde wirklich geschätzt werden. Seit ich mehr als einmal gegoogelt habe, bin ich auf diese Seite gelaufen, also habe ich große Hoffnungen.

+1

Die korrekte Verwendung von Bitfeldern besteht darin, keine Bitfelder zu verwenden. –

Antwort

17

Möglicherweise fehlt Ihnen eine Struktur in Ihrer Union.

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

Beachten Sie, dass die Reihenfolge von Mantisse/Exponent und Vorzeichen von der Endgültigkeit der CPU abhängt.

+0

Vielen Dank für Ihre Eingabe, aber warum eine Struktur in der Union hinzufügen? Ich habe die Verbindung der Teile des Schwimmers mit dem Schwimmer gemacht, um sicherzustellen, dass jedes Bitfeld dem entsprechenden Teil des Schwimmers entspricht. Ist das nicht genug? –

+1

Eine Union wird alle Mitglieder das gleiche Gedächtnis teilen. Ich glaube nicht, dass die Verwendung von Bitfeldern dieses Verhalten ändern wird, also beginnen alle Ihre Bitfelder bei Bit 0, genau wie der "Alles" -Float. Putting sie in einer Struktur macht das Layout sequenziell. – rmeador

+0

Sie hatten absolut Recht! Das war was benötigt wurde. Ich beschuldige mein Verständnis von Union dann :). Danke, mein Freund, jetzt kann ich nach Belieben auf jeden Teil meines Floats zugreifen. –

0

Das Problem ist, dass es eine Union ist. Es sollte "struct" sein.

0

Wenn Sie sich auf einer Glibc-Plattform befinden, können Sie sich die Header-Datei ieee754.h ansehen. Es kümmert sich um den Endianess-Kram. Wenn nicht, lohnt es sich trotzdem, einen Blick darauf zu werfen.