Extraktion eines Teilwortes?
-
Hier jetzt mal meinen Programmcode:
#include<iostream> using namespace std; int main() { unsigned int config_byte; unsigned int s, n, erg, x; unsigned int mask0, mask1, mask2, mask, anzahl; cout << "Bitte den Startwert s eingeben: s= "; cin >> s; cout << "Bitte die Anzahl der zu Extrahierenden Bits eingeben: n= "; cin >> n; config_byte = 0xF5C23D21; //Erstellen der Maske aufgrund der Benutzereingaben mask0 = 0xFFFFFFFF; mask1 = mask0 >> (31 - s); mask2 = mask0 << (31 - (s - n)); mask = mask1 & mask2; x = config_byte & mask; anzahl = 31 - (s - n); erg = x >> anzahl; cout << erg; system("pause"); return 0; }Das cout am Schluss liefert nicht das gewünschte Ergebnis... Wenn ich z.B. für s eine 11 (=12. Stelle der 32-Bit-Zahl) und für n eine 4 (um 4 Stellen zu maskieren) eingebe, dann liefert mir cout keine 13 (welche ja in Hex für ein D steht), sondern eine 0. Besser gesagt, er liefert mir für unterschiedliche Werte immer eine 0...
Was mach ich da noch falsch?
So der Grundgedanke dahiner kann doch gar nicht so falsch sein, oder?
-
bandchef schrieb:
Ich hab mir mal jetzt gedanken dazu gemacht und das so aufgezogen:
mask0 = 0xFFFFFFFF; mask1 = mask0 >> (31 - s); mask2 = mask0 << (31 - (s + n)); mask = mask1 & mask2;Stimmt das so? Was meint ihr?
Soll das jemand kapieren? Um eine Maske zu bekommen mit n gesetzten Bits, schreibe einfach
(1<<n) -1;Dann shifte des dahin wo Du willst und gut ist.
Mann macht's doch ned so komplexe Lösungen, die dann eh ned funktionieren.
mfg Martin
-
sorry, aber dein codeschnipsel verstehe ich nicht...
-
bandchef schrieb:
sorry, aber dein codeschnipsel verstehe ich nicht...
Wo ist das Problem? Das ist doch simpel:
1 << 7 = 10000000
10000000 - 1 = 11111111 << 2 = 100
100-1 = 11Ist jetzt der Groschen gefallen?
mfg Martin
-
1111111111111 >> 0000011111111 << 1111111111000 & ------------- 0000011111000Um die erste Zeil zu erstellen muss ich doch sagen: mask >> (32 - s); wie soll's denn sonst auch gehen.
Um die zweite Zeile zu erstellen muss ich doch auch sagen: mask0 << (32 - (s - (n-1)));
Keine Ahnung wie's anders gehen soll und schon gleich nicht wie das mit so 'nem kurzen Code wie dem hier gehen soll: (1<<n) -1;
-
siehst du bei mir das problem in der berechnung der zweiten "maske"?
-
Wo ist das Problem? Das ist doch simpel:
1 << 7 = 10000000
10000000 - 1 = 11111111 << 2 = 100
100-1 = 11Ist jetzt der Groschen gefallen?
mfg Martin
Sorry ich kapiers nicht...
EDIT: das obige beispiel verstehe ich jetzt schon aber ich kanns nicht auf mein Problem übertragen...
-
den rechts shift an die stelle die man mit s vorgibt kann ich ja nur damit erzeugen indem ich rechne: 32-s. und um genau diese Stellen muss ich nach rechts shiften.
damit ich weiß an welche stelle ich nach links shiften muss, dass genau 4 bits ausmaskiert werden muss ich halt auch wieder berechnen indem ich sag: (32 - (s - (n-1)))
aber genau dann funzts nicht. wie das mit deinem beispiel gehen soll ist mir überhaupt nicht klar.
-
bandchef schrieb:
Wo ist das Problem? Das ist doch simpel:
1 << 7 = 10000000
10000000 - 1 = 11111111 << 2 = 100
100-1 = 11Ist jetzt der Groschen gefallen?
mfg Martin
Sorry ich kapiers nicht...
EDIT: das obige beispiel verstehe ich jetzt schon aber ich kanns nicht auf mein Problem übertragen...
Du willst doch n hintereinander liegende Bits. Dazu brauchst Du eine Maske mit genau n hintereinander liegenden Bits. Du mußt nur noch die Maske dahin schieben, wo Du sie willst:
unsigned int maske = (1<<n)-1;Wenn Du die Bits beim höchstwertigen anfängst zu zählen und dort mit 1 anfängst, geht das so:
maske <<= (33-start-n)normalerweise fängt man aber beim niedrigsten mit 0 an zu zählen. Dann geht das so:
maske <<= start;Ergänzung:
So normalerweise will man dann aber, daß die maskierten Bits wieder an unterster Stelle stehen. Daher sollte man die Quelle shiften und mit den n bits der Maske maskieren und nicht die Maske shiften. Das erreichst Du letztendlich mit meinem ersten Lösungsvorschlag.mfg Martin
-
Ich hab eine solch Zahl gegeben:
1100011001010001Davon möchte ich jetzt die 7., 8., 9., ausmaskiert haben. Meine Stellen beginnen bei 1 und gehen in diesem Fall bis 12.
Dann schreibe ich:
mask = (1 << 10)-1;jetzt ist bis zur 9. Stelle maskiert. Und nun?
-
Um jetzt die zweite Maske bis von links nach Rechts bis zur 7. Stelle zu maskieren schreibe ich:
mask1 = (1 >> 6)-1;Muss ich da jetzt ebenfalls ein -1 schreiben?
-
aber auf mein Beispeil angewendet gehts wieder nicht:
mask1 = (1 << n)-1;
mask2 = (1 >> s)-1;den punkt s kann ich anshiften. mit n wird aber nur gegeben WIEVIELE bits maskiert werden sollen. und die wievielte stelle das nun eben in abhängigkeit von n sind, das MUSS man doch ausrechnen...

-
wahrscheinlich liegts auch daran weil ich es mir nicht vorstellen kann... gibts da nicht irgendwo eine schöne visualisierung wie man solche verdammten shifts macht?
-
bandchef schrieb:
Ich hab eine solch Zahl gegeben:
1100011001010001Davon möchte ich jetzt die 7., 8., 9., ausmaskiert haben. Meine Stellen beginnen bei 1 und gehen in diesem Fall bis 12.
Dann schreibe ich:
mask = (1 << 10)-1;jetzt ist bis zur 9. Stelle maskiert. Und nun?
Also ich habe jetzt 16 Bits gezählt.
1234567890123456
1100011001010001Du willst doch nur 3 Bits. Warum erzeugst Du dann eine Maske mit 10 Bits?
mask = (1<<3)-1; mask <<= 7;mfg Martin
-
bandchef schrieb:
wahrscheinlich liegts auch daran weil ich es mir nicht vorstellen kann... gibts da nicht irgendwo eine schöne visualisierung wie man solche verdammten shifts macht?
Das ist doch nicht schwer:
(1<<3) - 1 = 0000000000000111; 0000000000000111 << 1 = 0000000000001110; 0000000000000111 << 2 = 0000000000011100; 0000000000000111 << 3 = 0000000000111000; 0000000000000111 << 4 = 0000000001110000; 0000000000000111 << 5 = 0000000011100000; 0000000000000111 << 6 = 0000000011100000; 0000000000000111 << 7 = 0000000111000000; 0000000000000111 << 8 = 0000001110000000; usw. usf.mfg Martin
-
bandchef schrieb:
wahrscheinlich liegts auch daran weil ich es mir nicht vorstellen kann... gibts da nicht irgendwo eine schöne visualisierung wie man solche verdammten shifts macht?
Der Shift-Operator "<<" ist bereits eine Visualisierung von zwei Pfeilen die nach links gerichtet sind. Du schiebst alle Bits(auf der linken Seite von "<<") um ein gewisse Anzahl(auf der rechten Seite von "<<") nach links. Und ganz rechts werden Nullen aufgefüllt.
Die Anweisung 00001010<<2 kannst du so lesen: "00001010, nach links schieben, um 2" und erhältst dann 00101000.
-
Ich hab irgendwie den Eindruck, dass wir aneinander vorbei reden...
Meine Zahl beginnt bei der Stelle z0 (ganz rechts) und endet bei z15 (ganz links)
Ich hab z.B. eine 16-Bit zahl gegeben von der ich die 3., 4., 5. Stelle ausmaskieren möchte. Der Benutzer gibt dann eben in s eine 5 ein weil das der Punkt ist an der er starten möchte. Danach gibt der Benutzer an wieviele Bits er in Richtung des niederwertigsten Bits (also z0) "extrahieren" möchte.1101011011010110mask1 = ((1 << s)-1)Und bei der Maske2 weiß ich dann nicht mehr weiter...
-
bandchef schrieb:
Ich hab irgendwie den Eindruck, dass wir aneinander vorbei reden...
Meine Zahl beginnt bei der Stelle z0 (ganz rechts) und endet bei z15 (ganz links)
Ich hab z.B. eine 16-Bit zahl gegeben von der ich die 3., 4., 5. Stelle ausmaskieren möchte. Der Benutzer gibt dann eben in s eine 5 ein weil das der Punkt ist an der er starten möchte. Danach gibt der Benutzer an wieviele Bits er in Richtung des niederwertigsten Bits (also z0) "extrahieren" möchte.1101011011010110mask1 = ((1 << s)-1)Und bei der Maske2 weiß ich dann nicht mehr weiter...
Wozu zwei Masken? Eine genügt:
s = 5; n = 3; unsigned int mask = (1<<n)-1; mask <<= s-n;voila. Da Dir scheinbar selber nicht ganz klar ist, ob Du nun bei 0 oder 1 anfängst zu zählen und wo Du anfängst, musst Du Dir die zweite Zeile selber so hindrehen, wie Du's brauchst.
-
Ich hab's immer noch nicht.
Ich möchte aus einer 32-Bit Zahl ab einer beliebigen Startposition s beliebig viel Bits n ausmaskieren.
Jetzt hab ich anscheinend mittlerweile zwei Optionen. Entweder die von Seppj indem ich zwei Masken mache bei der ich die erste nach rechts shifte auf die Position von s und die zweite nach links shifte auf die Position die sie sich aus n und s ergibt. Danach verunde ich die beiden Masken. Wenn die beiden Masken verundet sind verunde ich mein Configbyte mit der enstandenen Maske. Ich würde es gerne so machen.
So stell ich es mir vor:
11111111 Ausgangsmaske 00011111 1. Maske (Ausgangsmaske >> 3) wobei 3 = 8- s 00011100 2. Maske (Ausgangsmaske << ???) 00011100 (1. Maske) & (2. Maske)So sollte es doch gehen oder? Jetzt get's mir eben darum wie ich die 2. Maske in Abhängigkeit von s und n auf die richtige Position shifte.
Kann mir das jemand erklären?
-
Irgendwie glaub ich mittlerweile funktioniert das shiften bei mir überhaupt nicht. Ich hab mir jetzt mal ein Programm gestrickt, dass einfach eine 32-Bit-Zahl gegeben durch eine Hex-Konstante der Form 0xFFFFFFFF einfach um 4 Stellen nach rechts shiften soll. Wenn er das tun würde, würde doch dann als Ergebenis 0xFFFFFFF = 268435455(dezimal) rauskommen, was es aber nicht tut. Was mach ich denn nur falsch?
Kann mir einer sagen was hier jetzt falsch ist? Kann man unsigned int nicht shiften? Darf ich keine Hexzahlen verwenden? Verwende ich die Shiftoperatoren falsch? Bitte helft mir!