Forum: Mikrocontroller und Digitale Elektronik Bit-Maskierung 32bit


von Joachim B. (jojo84)


Lesenswert?

Hallo Forum!

Ich hab mal eine Frage zur Maskierung von Bits. Das ist bestimmt ganz 
einfach, aber ich bin einfach nicht sicher, also:

Ich habe eine 32bit-Variable. Aus dieser möchte ich eine bestimmte 
Anzahl Bits von einer Bieliebigen Stelle an maskieren und dann in einer 
char-Variablen (8bit) abspeichern.
Beispiel mit 16 bit:
unsigned int x = 0x2BC5 ( = 0010101111000101)

Jetzt möchte ich z.B. NUR Bit 6-12 in einer char speichern, ungefähr 
so:

unsigned char y = 0x2F ( = 00101111)

würde das gehen, wenn ich das wie folgt mache?

y = (x & 0x1FC0);

Danke und schönen Tag noch,
Jojo

von Jörg G. (joergderxte)


Lesenswert?

>würde das gehen, wenn ich das wie folgt mache?
>y = (x & 0x1FC0);
Nein, denn in dem unsigned char bleiben nur die untersten 8 Bits.
Aber du bist schon fast am Ziel:
1
unsigned char y;
2
y = (x & (0x2F << 6)) >> 6;
3
//                       ^ Auf Bit 0 verschieben
4
//                ^ Ab Bit 6
5
//        ^^^^ 6Bits

hth, Jörg

von Joachim B. (jojo84)


Lesenswert?

Hi und danke für die Antwort!

Ja, das mit dem Schieben hatte ich auch fast schon im Hinterkopf. War 
mir aber nicht sicher, da dachte ich: lieber mal nachfragen. Hat sich ja 
gelohnt :)

Schönen dank!

von Kasperle (Gast)


Lesenswert?

unsigned char y;
y = (x & (0x2F << 6)) >> 6;
//                       ^ Auf Bit 0 verschieben
//                ^ Ab Bit 6
//        ^^^^ 6Bits

Sollte es nicht 0x3F << 6 sein für 6 bits?
Oder irre ich mich?

von Quentchen (Gast)


Lesenswert?

>Oder irre ich mich?
Nein.

von Joachim B. (jojo84)


Lesenswert?

Ja, das hatte ich auch bemerkt. Aber das war mir wurscht, weil es mir ja 
ums Prinzip ging. Aber irgendwie klappt es noch nicht ganz. Wäre toll, 
wenn einer von euch mal einen Blick auf den folgenden Code wirft :)

In der h-Datei:
1
int masking(long x, int mask, int shift);

Aufruf dann z.B. so:
1
y1 = masking(variable, 0x7F, 0);
2
y2 = masking(variable, 0x3F, 7);

Und in der masking() steht z.B.:
1
int masking(long x, int mask, int shift)
2
{
3
  unsigned char temp = (x & (mask << shift) ) >> shift);
4
5
return temp;
6
}

In temp, bzw. y1 und y2 steht totaler Mumpitz. Muß ich erst noch was 
casten, was ich übersehen habe?

Danke und viele Grüße,
Jojo

von Kai G. (runtimeterror)


Lesenswert?

Das hier sollte es auch tun:
1
return (x >> shift) & mask;

von Joachim B. (jojo84)


Lesenswert?

Ok, danke. Das werd ich nachher mal probieren. Aber dennoch wüßte ich ja 
gern, wo der Haken bei meinem Code liegt. Er erschien mir schon 
irgendwie logisch, aber wenns nciht geht? Ich weiß ja nicht...

Edit:
wie siehts mit den Datentypen aus? Die müßten doch eigentlich so passen, 
oder? o_O

von Karl H. (kbuchegg)


Lesenswert?

Joachim A. schrieb:

Kai hat zwar schon gezeigt, wie es einfacher geht ...

> In temp, bzw. y1 und y2 steht totaler Mumpitz. Muß ich erst noch was
> casten, was ich übersehen habe?

wenn mask ein int ist, was ist dann wohl das Ergebnis von
   mask << shift

von Kai G. (runtimeterror)


Lesenswert?

Was stand denn in deinem Testfall in variable, was war das Ergebnis 
und was hattest du erwartet?

>Edit:
>wie siehts mit den Datentypen aus? Die müßten doch eigentlich so passen,
>oder? o_O

Auf Anhieb sehe ich keinen Fehler. Wie breit sind denn bei dir long, int 
und char? Gab's bei C nicht auch unsigned typen? Ich denke die sind 
besser für solche Operationen geeignet.

von Kai G. (runtimeterror)


Lesenswert?

>wenn mask ein int ist, was ist dann wohl das Ergebnis von
>   mask << shift

int - aber ich sehe bei seinem ersten Testfall kein Problem ...

von Joachim B. (jojo84)


Lesenswert?

Hi und nochmal danke für eure Hilfe!

Ich glaub ich hab es jetzt hinbekommen. Das Problem schien aber schon 
weiter vorher in meinem Programm seinen Ursprung gehabt zu haben. Denn 
im Laufe einiger Optimierungen hab ich auch einige Datentypen verändert, 
was scheinbar nicht so gut war.
Naja, jetzt scheint es zu funktionieren! Ich benutze das, um die 
Bitfolge des DCF77-Signals aus zu werten. Vorher hatte ich, so wie auch 
in dem Beispiel hier auf der Seite, alle Bits einzelnd abgefragt. Das 
funktionierte zwar gut, aber mein Code ist jetzt schneller und 
verbraucht deutlich (>10%) weniger Speicher =) .

Also, danke und Schönes Wochenende!

von Kai G. (runtimeterror)


Lesenswert?

Noch eine Kleinigkeit: Meiner Meinung nach spricht nichts dagegen, 
mask und shift auf den Typ unsigned char zu setzen, wenn man die 
von mir vorgeschlagene Variante einsetzt. x würde ich auf /unsigned 
long/ setzen.

von Karl H. (kbuchegg)


Lesenswert?

Kai Giebeler schrieb:
>>wenn mask ein int ist, was ist dann wohl das Ergebnis von
>>   mask << shift
>
> int - aber ich sehe bei seinem ersten Testfall kein Problem ...

Bei seinen Testfällen gibt es eh kein Problem.
Aber wenn man eine Funktion allgemein halten will sodass sie mit allen 
Zahlen klarkommt, dann bekommt seine Version ein Problem.

Da ist deine Variante viel besser.

Beitrag #5620046 wurde von einem Moderator gelöscht.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.