El problema: Ejercicio 2-8 de The C Programming Language, "Escribir una función rightrot (x, n) que devuelve el valor del entero x, rotado a la derecha por n posiciones."Rotación de bits en C
He hecho esto de todas las maneras que sé cómo. Aquí está el problema que estoy teniendo. Tome un número determinado para este ejercicio, digamos 29, y gírelo a la derecha en una posición.
11101 y se convierte en 11110 o 30. Digamos por el argumento de que el sistema en el que estamos trabajando tiene un tamaño de tipo entero sin signo de 32 bits. Digamos además que tenemos el número 29 almacenado en una variable entera sin signo. En la memoria, el número tendrá 27 ceros por delante. Entonces, cuando giramos 29 a la derecha usando uno de varios algoritmos que muestro a continuación, obtenemos el número 2147483662. Evidentemente, este no es el resultado deseado.
unsigned int rightrot(unsigned x, int n) {
return (x >> n) | (x << (sizeof(x) * CHAR_BIT) - n);
}
Técnicamente, esto es correcto, pero yo estaba pensando que los 27 ceros que están frente a 11101 fueron insignificantes. También he intentado un par de otras soluciones:
int wordsize(void) { // compute the wordsize on a given machine...
unsigned x = ~0;
int b;
for(b = 0; x; b++)
x &= x-1;
return x;
}
unsigned int rightrot(unsigned x, int n) {
unsigned rbit;
while(n --) {
rbit = x >> 1;
x |= (rbit << wordsize() - 1);
}
return x;
Esta última y definitiva solución es aquel en el que pensé que lo tenía, voy a explicar donde fracasó una vez que llegar a la final. Estoy seguro de que se pueden ver mi error ...
int bitcount(unsigned x) {
int b;
for(b = 0; x; b++)
x &= x-1;
return b;
}
unsigned int rightrot(unsigned x, int n) {
unsigned rbit;
int shift = bitcount(x);
while(n--) {
rbit = x & 1;
x >>= 1;
x |= (rbit << shift);
}
}
Esta solución da la respuesta esperada de 30 que yo estaba buscando, pero si se utiliza un número para x como oh digo 31 (11111), a continuación, hay problemas, específicamente el resultado es 47, usando uno para n. No pensé en esto antes, pero si se usa un número como 8 (1000), entonces el caos. Solo hay un bit establecido en 8, por lo que el cambio seguramente será incorrecto. Mi teoría en este momento es que las dos primeras soluciones son correctas (principalmente) y me falta algo ...
Tomaré eso para decir que el comportamiento de los dos primeros ejemplos fue correcto, y no me estoy volviendo loco. – Brandon
No estoy seguro de su suposición de que 2147483662 es la respuesta incorrecta. ¡Me parece bien! La pregunta dice "el entero x", lo que implica una cierta cantidad de bits en x, p. 32. De lo contrario, ¿debería el rightrot (1,1) devolver siempre 1? –
Sr. Lister, concedo por completo. Aparentemente hay algunas concepciones que tenía sobre Binay, la forma en que se almacenan y la forma en que se interpreta que fueron incorrectas. Supuse que el valor estaba mal en primer lugar, porque estaba tomando los 27 ceros que proceden el valor que estaba usando en la memoria para que no sean significativos para ese valor. y entiendo lo que dices sobre uno. Si el rightrot (1,1) siempre devolvió 1, entonces, ¿cómo podría girar uno a la izquierda como 1000 o 10000000000000000000000000000000? – Brandon