mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Bit-Maskierung 32bit


Autor: Joachim B. (jojo84)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg G. (joergderxte)
Datum:

Bewertung
0 lesenswert
nicht 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:
unsigned char y;
y = (x & (0x2F << 6)) >> 6;
//                       ^ Auf Bit 0 verschieben
//                ^ Ab Bit 6
//        ^^^^ 6Bits 

hth, Jörg

Autor: Joachim B. (jojo84)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Kasperle (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Quentchen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Oder irre ich mich?
Nein.

Autor: Joachim B. (jojo84)
Datum:

Bewertung
0 lesenswert
nicht 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:
int masking(long x, int mask, int shift);

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

Und in der masking() steht z.B.:
int masking(long x, int mask, int shift)
{
  unsigned char temp = (x & (mask << shift) ) >> shift);

return temp;
}

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

Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das hier sollte es auch tun:
return (x >> shift) & mask;

Autor: Joachim B. (jojo84)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht 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 ...

Autor: Joachim B. (jojo84)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.