Extraktion eines Teilwortes?
-
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!
-
Wie sollen wir das beantworten, wenn du uns nicht zeigst, was du genau gemacht hast?
Die Shift-Operatoren werden aber sicherlich funktionieren, der Fehler liegt bestimmt bei dir...
-
Das der Fehler bei mir liegt ist klar...

Hier mein code:
#include<iostream> using namespace std; int main() { unsigned int mask1, mask2; mask1 = 0xFF; mask1 = mask1 >> 3; cout << "Maske1 um 3 nach rechts geshiftet: " << mask1 << endl; mask2 = 0xFF; mask2 = mask2 >> 3; cout << "Maske2 um 3 nach links geshiftet: " << mask1 << endl; system("pause"); return 0; }Ich shifte 0xFF für die Maske1 um 3 nach rechts. Da kommt dann dezimal 63 raus was auch korrekt ist.
Für die zweite Maske shifte ich 0xFF um 3 nach links. Da kommt dann laut meinem Programm wieder 31 raus was aber falsch ist, da 11111000 nicht gleich 31 sondern gleich 248 im Dezimalsystem ist.
Könnt ihr mir sagen was im Fall des Linksshifts schief läuft?
-
Ich shifte 0xFF für die Maske1 um 3 nach rechts. Da kommt dann dezimal 63 raus was auch korrekt ist.
Richtig wäre aber 31.
Für die zweite Maske shifte ich 0xFF um 3 nach links.
Laut Code shiftest du 3 nach rechts.
Da kommt dann laut meinem Programm wieder 31 raus[...]
Für den rechtsshift um 3 ist das auch richtig.
-
Danke Danke!
Jetzt sehe ich's. Ich hab den Code jetzt geändert. Jetzt sieht er so aus:
#include<iostream> using namespace std; int main() { unsigned int mask1, mask2, mask, a, b; mask1 = 0xFF; mask1 = mask1 >> 3; cout << "Maske1 um 3 nach rechts geshiftet: " << mask1 << endl; mask2 = 0xFF; mask2 = mask2 << 3; cout << "Maske2 um 3 nach links geshiftet: " << mask2 << endl; mask = mask1 & mask2; cout << "Maske:" << mask << endl; system("pause"); return 0; }Wenn ich jetzt das Programm laufen lasse, dann bekomme ich für die Maske2 2040. Das Ergebnis des Linksshifts ist zwar nicht korrekt (korrekt wäre 248) aber das Ergebnis der Verundung der beiden Masken stimmt dann wieder...; nämlich 24...
Was ist da jetzt los?
-
bandchef schrieb:
Das Ergebnis des Linksshifts ist zwar nicht korrekt (korrekt wäre 248)
[...]
Was ist da jetzt los?
Du kannst nicht rechnen.
-
bandchef schrieb:
Das Ergebnis des Linksshifts ist zwar nicht korrekt (korrekt wäre 248)
[...]
Was ist da jetzt los?
Du gehst davon aus das dein unsigned int 8 bits lang ist. Das stimmt aber nicht, dein unsigned int ist sehr wahrscheinlich 32 bits lang(evtl. 64). Dementsprechend bekommst du natürlich 0000 0000 0000 0000 0000 0111 1111 1000(2040) und nicht 1111 1000(248), weil nix abgeschnitten wird.
Edit:Formatierung geändert
-
Danke für eure Hilfe!
Ich hab jetzt mein Programm soweit fertiggestellt.
Hier der Code:
#include<iostream> using namespace std; int main() { unsigned int config_byte, mask, mask1, mask2, mask3, erg, s, n, x, y; cout << "Bitte den Startwert s eingeben: s="; cin >> s; cout << "Bitte die Anzahl der zu Extrahierenden Bits eingeben: n="; cin >> n; config_byte = 0xF5C23D21; mask1 = 0xFFFFFFFF; x = (32 - s); mask1 = mask1 >> x; cout << "Maske1 um " << x << " nach rechts geshiftet: " << mask1 << endl; mask2 = 0xFFFFFFFF; y = (s - n); mask2 = mask2 << y; cout << "Maske2 um " << y << " nach links geshiftet: " << mask2 << endl; mask = mask1 & mask2; cout << "eigentliche Maske: " << mask << endl; mask = mask & config_byte; cout << "extrahiertes Teilwort, aber noch an der falschen Stelle: " << mask << endl; mask = mask >> (s - n); cout << "extrahiertes Teilwort=" << mask << endl; system("pause"); return 0; }Bei der Aufgabe wurden folgende Einschränkungen bezüglich der Eingabe von s und n gemacht: Sie dürfen davon ausgehen, dass s grundsätzlich kleiner als 32 und immer größer 0 ist, sowie n immer gleich s+1 ist.
Mit diesen Einschränkungen funzt das Programm jetzt.
Wenn ihr wollt könnt ihr ja jetzt gerne Überprüfen!
Danke!
-
bandchef schrieb:
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?
So geht's:
1. Du hast 'nen 32-Bit-wert:
`10987654321098765432109876543210XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
`
Die erste Zeile ist zum Durchnumerieren der Bits. Die X stellen Deinen 32-Bitwert dar.2. Du willst die Bits 28 bis 19 maskieren:
1.Maske
`1098765432109876543210987654321011111111111111111111111111111111
3 (31-28) Bits nach rechts00011111111111111111111111111111`2. Maske
`1098765432109876543210987654321011111111111111111111111111111111
19 Bits nach links11111111111110000000000000000000`3. Maske
1. Maske & 2 Maske
`0001111111111111111111111111111111111111111110000000000000000000
00011111111110000000000000000000`
4. Ergebnis = 32-Bit Wert & 3. Maske
`10987654321098765432109876543210XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
00011111111110000000000000000000
000XXXXXXXXXX0000000000000000000`
Jetzt kapiert?
Achte darauf, daß die Masken 1-3 in unsigned variablen gespeichert sind, sonst funktioniert es nicht.
mfg Martin
-
bandchef schrieb:
mask1 = 0xFFFFFFFF;
Wenn Du eine unsigned variable mit allen gesetzten Bits brauchst, schreibe entweder
unsigned int xvy = -1;
oder
unsigned int xyz = UINT_MAX;
Dann funktioniert Dein Code auch mit 64-Bit Prozessoren.
mfg Martin