Rotación derecha de bits en C

Jan 03 2021

Estoy trabajando en el ejercicio 2-8 en K&R, que nos pide que escribamos la función de rightrot(int x, int n)modo que todos los bits de xse desplacen n veces hacia la derecha y los bits que caen del extremo derecho reaparecen en el extremo izquierdo.

Aquí está mi intento de solución en el que cambio cada bit uno por uno:

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;
}

Cuando ejecuto rightrot(122, 2), espero obtener 94ya que 122es 1111010y 94es 1011110. En cambio, entiendo lo 30que resulta ser 0011110. Claramente, mi método para configurar el bit más a la izquierda no funciona como esperaba. ¿Alguien detecta un error obvio? Estoy aprendiendo a capturar bits y cosas por el estilo.

NOTA: Obtuve la técnica para configurar el bit más a la izquierda de esta publicación.

Respuestas

7 mch Jan 02 2021 at 23:21

Analicemos (~0 ^ (~0 >> 1) ):

~0es de -1
~0 >> 1nuevo -1, si el bit de signo es 1righthift llenará los nuevos bits con 1s.
-1 ^ -1es 0.
x = x | 0es x.

La solución es que debe utilizar tipos de datos sin firmar si desea realizar bitoperaciones.

Por lo tanto, debe usar la línea x = x | (~0u ^ (~0u >> 1) );
Para evitar otros problemas, el parámetro xtambién debe ser unsigned int.

https://ideone.com/7zPTQk