Rechtsdrehung der Bits in C.

Jan 03 2021

Ich arbeite an Übung 2-8 in K & R, in der wir aufgefordert werden, die Funktion rightrot(int x, int n)so zu schreiben , dass alle Bits von xn-mal nach rechts verschoben werden, wobei die Bits, die vom rechten Ende abfallen, am linken Ende wieder erscheinen.

Hier ist mein Lösungsversuch, bei dem ich jedes Bit einzeln verschiebe:

int rightrot(int x, int n)
{
    int i, rmb;

    for(i = 0; i < n; ++i)
    {
        // get right-most bit
        rmb = x & 1;

        // shift 1 to right
        x = x >> 1;

        // if right-most bit is set, set left-most bit
        if (rmb == 1)
            x = x | (~0 ^ (~0 >> 1) );
    }

    return x;
}

Wenn ich ausführe rightrot(122, 2), erwarte ich, dass es 94da 122ist 1111010und 94ist 1011110. Stattdessen bekomme ich 30was zufällig ist 0011110. Es ist klar, dass meine Methode zum Setzen des Bits ganz links nicht so funktioniert, wie ich es erwartet habe. Hat jemand einen offensichtlichen Fehler entdeckt? Ich lerne gerade, wie man Teile und ähnliches erfasst.

HINWEIS: Ich habe die Technik zum Setzen des am weitesten links stehenden Bits aus diesem Beitrag erhalten.

Antworten

7 mch Jan 02 2021 at 23:21

Lassen Sie uns analysieren (~0 ^ (~0 >> 1) ):

~0ist -1
~0 >> 1wieder -1, wenn das Vorzeichenbit die 1Rechtsverschiebung ist, werden die neuen Bits mit 1s gefüllt .
-1 ^ -1ist 0.
x = x | 0ist x.

Die Lösung besteht darin, dass Sie vorzeichenlose Datentypen verwenden sollten, wenn Sie Bitoperationen ausführen möchten.

Sie sollten also die Zeile verwenden, x = x | (~0u ^ (~0u >> 1) );
um andere Probleme zu vermeiden. Der Parameter xsollte auch sein unsigned int.

https://ideone.com/7zPTQk