Rotación derecha de bits en C
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 x
se 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 94
ya que 122
es 1111010
y 94
es 1011110
. En cambio, entiendo lo 30
que 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
Analicemos (~0 ^ (~0 >> 1) )
:
~0
es de -1
~0 >> 1
nuevo -1
, si el bit de signo es 1
righthift llenará los nuevos bits con 1
s.
-1 ^ -1
es 0
.
x = x | 0
es 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 x
también debe ser unsigned int
.
https://ideone.com/7zPTQk