Bitoperation (ROL in festgelegter Breite)



  • Jetzt kommt meine große Schwäche, Bitoperationen. Ich würde gerne einen 32 Bit wert folgendermaßen aufteilen:

    4 Bit eine fest zahl die sich nie ändert
    die anderen 28 Bit: dort soll immer folgendes geschehen:
    Rotation der 28 Bit um 2 Bit, XOR mit einen Wert der 2 Bit groß ist.
    D.H. die ersten 4 Bit ändern sich nie, die anderen 28 Bit sind einen wandel unterzogen. Wie löse ich das am besten. Aktuell hab ich für C# eine Funktion gefunden die zumindest eine Rotation um 2 Bit ermöglicht.

    (ret << 2) | (ret >> (30));

    Das ganze funktioniert aber nur mit den vollen 32 Bit, ich denke mal ich muss wohl die festgelegten 4 Bits ausmaskieren bevor ich das ganze mache.


  • Administrator

    Grob geschätzt wohl so:

    uint val = 0x9BFFFFFD;          // val: 1001 1011 1111 1111 1111 1111 1111 1101
    uint fix = val & 0xF0000000;    // fix: 1001 0000 0000 0000 0000 0000 0000 0000
    
    val &= 0xFFFFFFF;               // val: 0000 1011 1111 1111 1111 1111 1111 1101
    val = (val << 2) | (val >> 26); // val: 0010 1111 1111 1111 1111 1111 1111 0110
    
                                    // hier noch die xor Operation durchführen.
    
    val &= 0xFFFFFFF;               // val: 0000 1111 1111 1111 1111 1111 1111 0110
    val |= fix;                     // val: 1001 1111 1111 1111 1111 1111 1111 0110
    

    Falls die fixierten 4 Bits auf der anderen Seite sind, musst du halt die Offsets bei den Shift-Operationen und die Masken anpassen.

    Falls du nicht uint verwendest, wird es etwas schwieriger. Zum Beispiel beim Right-Shift musst du auf der Hut sein. Das Ding verhält sich arithmetisch korrekt:

    int i = -0xF0;
    i >>= 4;
    
    // Dies ergibt für i: 1000 0000 0000 0000 0000 0000 0000 1111
    

    Also minus 15. Das Vorzeichenbit bleibt von der Shift-Operation unberührt. Bei uint passiert das nicht, aber da gibt es ja auch kein Vorzeichenbit 😉

    Auch geht dies Operation nicht so einfach mit int :

    int fix = val & 0xF0000000;
    

    Die Hexzahlen werden als uint Zahlen angenommen. Man müsste sie daher in negative Dezimalzahlen umrechnen, was alles andere als optimal aussieht:

    int fix = val & -268435456;
    

    Grüssli



  • Besten dank schonmal. Klappt gut. Rein der Interessenhalber zum int, was genau ist das problem dort? Beim Shift bleibt immer das Vorzeichbit unberührt? Es wird also nur 1-31 Geshiftet ? Oder hab ich das falsch Verstanden.


  • Administrator

    Fedaykin schrieb:

    Besten dank schonmal. Klappt gut. Rein der Interessenhalber zum int, was genau ist das problem dort? Beim Shift bleibt immer das Vorzeichbit unberührt? Es wird also nur 1-31 Geshiftet ? Oder hab ich das falsch Verstanden.

    Genau.
    Problematisch ist aber auch, dass man nicht einfach das das Vorzeichenbit wegmaskieren kann, bzw. dazu eben negative Dezimalwerte verwenden muss, was einfach nur befremdlich wirkt. Wenn man Bitoperationen durchführt in C#, sollte man wenn möglich einen vorzeichenlosen Typ nehmen. Erspart einem eine Menge Probleme.

    Grüssli


Log in to reply