Bit masking

Hallo,

wie kann ich mehrere kleine Werte in eine 32 bit Integer variable verpacken ? Das wird in meinem Buch nicht einleuchtend erklärt und im Internet finde ich nirgends was.

Wenn ich z.b. nur die ersten 3 bits ansprechen will um da was reinzuspeichern (Die Werte liegen zwische 0-5), und dann die nächsten 3 bits und so weiter. Wie mach ich das und wie lese ich die Werte dann wieder aus ?

Wenn ich z.b. nur die ersten 3 bits ansprechen will um da was
reinzuspeichern (Die Werte liegen zwische 0-5), und dann die
nächsten 3 bits und so weiter. Wie mach ich das und wie lese
ich die Werte dann wieder aus ?

Für das Setzen bin ich mir gerade nicht sicher ob es eine einfachere Lösung gübt, mir fällt aber keine andere ein:

Zunächst musst du die entsptechenden Bits im bestehenden Container auf 0 setzen und dann deinen Wert durch bit shift entsprechend verschieben und mit dem oder Operator die bits setzen, also etwa so (das int& soll eine referenz auf container sein, bin mir nicht sicher wie die richtige pointerschreibweise ist :smile:

void setValueAtPosition(int& container, int value, int position) {
 // erzeuge eine bitmaske die überall einsen hat, aber die drei bits an der gewünschen stelle sind null
 int deletemask = ~(7 






Das auslesen ist einfach. Du musst nur die Werte um entsprechend viele bits nach rechts verschieben (also beim zweiten Wert 3 bits, beim dritten 6 bits, usw.) und dann das Ergebnis mit 7 (binär: 111) verunden um alle evtl. sonst vorkommenden einsen wegzuschmeissen.

Also:


int getValueAtPosition(int& container, int position) {
 return (container \>\> (position \* 3)) & 7;
}

Hallo FrageWurm,

wie kann ich mehrere kleine Werte in eine 32 bit Integer
variable verpacken ? Das wird in meinem Buch nicht
einleuchtend erklärt und im Internet finde ich nirgends was.

Wenn ich z.b. nur die ersten 3 bits ansprechen will um da was
reinzuspeichern (Die Werte liegen zwische 0-5), und dann die
nächsten 3 bits und so weiter. Wie mach ich das und wie lese
ich die Werte dann wieder aus ?

typedef union 
{
 long all\_bits;
 struct
 {
 long Pack1 :3; // 3 bits gross
 long NochSoWas :1; // nur 1 Bit
 } s;
} GEPACKTE\_BITS;

void f(void)
{
 GEPACKTE\_BITS x;
 long l;

 x.all\_bits = 0; // Alle bits auf 0 setzen

 x.s.Pack1 = 5;
 x.s.NochSoWas = TRUE;
}

Weiteres ist unter dem Stichwort „bitfields“ zu finden.

MfG Peter(TOO)

Als Ergänzung die minimalversion
Hallo FrageWurm,
Auch wenn man es am Ende genauso machen sollte, wie Peter schreibt, hier auch der Teil worauf es ankommt: Structs (fast gleiche Funktion wie bei Peter)

struct
{
long Pack1 :3;
long NochSoWas :1;
}y;

void f(void)
{
y.Pack1 = 5;
y.NochSowas = True;
}

Hier ist y direkt eine Variable, die du Benutzen kannst, und die beim Programmstart 0 ist.

Peter hat dann aus y eine union gemacht, um auf alle Bits gleichzeitig zugreifen zu können, (und auch um die Größe der Variablen auf 32bit festzulegen). Und dann kommt typedef ins spiel, das zwar erst umständlich ist, weil man erst den Typ definiert (typedef union), und dann eine Variable davon anlegen muß (x). In der Praxis ist es aber vorteilhat, wenn man evt. mehrere Variablen mit dieser Bitaufteilung anlegen will, und sei es nur, um z.B. den alten Zustand der Bits zwischenzuspeichern.

Hallo Achim,

Auch wenn man es am Ende genauso machen sollte, wie Peter
schreibt, hier auch der Teil worauf es ankommt: Structs (fast
gleiche Funktion wie bei Peter)

Die Frage war doch:
Wie kann ich mehrere kleine Werte in eine 32-Bit Variable verpacken ?
Dies impliziert für mich, dass das Ganze auch als 32-Bit bearbeitet werden können muss.
Hinzu kommt noch die Aussage, dass dieser Punkt nicht in seinem Buch besprochen wird, ich finde es aber sehr Unwarscheinlich, dass bitfields nicht in einem C-Buch beschrieben werden.

Hier ist y direkt eine Variable, die du Benutzen kannst, und
die beim Programmstart 0 ist.

Dies trifft aber NUR dann zu, WENN er die Variable NICHT im Funktions-Rumpf (Autovariable) deklariert !!!
Eine Auto-Variable enthällt am Anfang immer nur Schrott !!!

MfG Peter(TOO)

Hallo Peter,

Hinzu kommt noch die Aussage, dass dieser Punkt nicht in
seinem Buch besprochen wird, ich finde es aber sehr
Unwarscheinlich, dass bitfields nicht in einem C-Buch
beschrieben werden.

guter Punkt, dachte das Strukturen unbekannt sind.

Ansonsten, wenn Strukturen genutzt werden, ohne union mit integer-Wert, nochmal eine alternative, so wie ich sie aus Bequemlichkeit verwende:

Gegeben sei eine Struktur x, die durch Alignment oder Summe der Inhalte 32-bit breit sei:

#define UI32ACCESS(variable) (*((unsigned long *)(&variable)))
void f(void)
{
x.Paket1 = 5; // setzt den Strukturteil Paket1 in x auf 5
UI32ACCESS(x) = 0; //löscht alle bits zu 0
}

Dies ist immer gefährlich, nicht sehr sauber, aber z.B. auch auf Strukturen anwendbar, die man nicht in der Hand hat, die also extern deklariert und in libraries verwendet werden. Das Define sollte sein, da ein vergessenes & oder * nicht immer wirklich auffallen muß.

achim