Extraktion eines Teilwortes?



  • 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 = 1111111

    1 << 2 = 100
    100-1 = 11

    Ist jetzt der Groschen gefallen?

    mfg Martin



  • 1111111111111
    
    >> 0000011111111
    << 1111111111000
    &  -------------
       0000011111000
    

    Um 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 = 1111111

    1 << 2 = 100
    100-1 = 11

    Ist 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 = 1111111

    1 << 2 = 100
    100-1 = 11

    Ist 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:

    1100011001010001
    

    Davon 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:

    1100011001010001
    

    Davon 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
    1100011001010001

    Du 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.

    1101011011010110
    
    mask1 = ((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.

    1101011011010110
    
    mask1 = ((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!


  • Mod

    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...


Anmelden zum Antworten