Extraktion eines Teilwortes?


  • Mod

    Rechenfehler meinerseits ignorieren, es geht um's Prinzip:

    0xFF = 11111111
      64 = 01000000
    
    0xFF & 64 = 01000000 = 64
    

    Fehler verstanden?



  • Hm, ok,

    Der compiler liefert mir eine 64 weil eben 01000000 einer 64 entspricht. Aber wie bringe ich ihn dazu, dass er mir eben nur eine 1 oder 0 auswirft?



  • Einfach überprüfen, ob 0 (oder != 0) als Ergebnis der Maskierung rauskommt:

    int eins_oder_null = (config_byte & mask)? 1 : 0;
    


  • das darf ich nicht...


  • Mod

    Dann shifte das Ergebnis. Shiften wirst du ohnehin müssen bei der Aufgabenstellung.



  • Nach der maskierung die eins einfach nach links shiften... das wars jetzt funzts so wie ich will... danke.

    Das Startbit setze ich jetzt so:

    cin >> s;
    
        x = a & (1 << s);
        z = x >> s;
    

    Ich bekomme danach je nach dem eine 1 oder 0. Jetzt hab ich allerdings noch das problem, dass ich nicht weiß wie ich ohne Schleifen aus einer 32-bit langen Zahl ab einem Startbit (s) z.B. eine n-lange Bitkette "rausschneide". Irgendwie kann doch das gar nicht gehen, oder?



  • So ungefähr könnte das gehen

    int int32 = ....;
    int start = ...;
    int num = ...;
    
    int mask = (1<<num)-1;
    int result = (int32 >> start) & mask;
    

    mfg Martin


  • Mod

    Um eine n-stellige Maske zu erstellen: Nimm eine Maske nur aus Einsen, shifte sie einmal entsprechen nach links und einmal nach rechts und verunde das Ergebnis. So:

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


  • 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?



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


Anmelden zum Antworten