ayuda con operaciones a nivel de bits y mascaras

Iniciado por redpeli20, 30 Mayo 2015, 20:16 PM

0 Miembros y 1 Visitante están viendo este tema.

redpeli20

El Problema es el Siguiente: Debo realizar este programa en C

Recibo un número (entero sin signo) y según el carácter a su derecha, se debe sustituir todas las coincidencias de ese carácter en el número por el valor 0 (cero). Acá un ejemplo:

La entrada es "25798 6" entonces 25798 en hexadecimal es 0x000064C6 y el carácter en la entrada es 6. Por medio de operadores y uso de mascaras, debo sobrescribir el número eliminando el 6 y escribiendo 0 (cero) en su lugar.

El número resultante es 1216 que es hexadecimal es 0x000004C0. Como resultado debo imprimir por pantalla 1216

Las operaciones que puedo usar son las siguientes:
!
~
^
&
|
+
<<
>>

No esta permitido el uso de arreglos.

Mod: No escribir en mayúsculas

0xFer

#1
Bienvenido al foro

Primero tendrias que haces una mascara que contenga el último dígito así:

unsigned int mascara = num & 0xF;

EL 0xF e Binario sería: 0000 .... 1111, al aplicar un and lógico sobre el 0xF y el número como resultado se obtiene el último dígito del número en hexadecimal

Luego:


int i;
int bitsnum;
  for(i = 0; i < 8;i++){
 
      bitsnum = num & 0xF << i*4;
       if( (mascara ^ (bitsnum ) ) == 0){
           num = (num ^ mascara);
       }
         
      mascara <<= 4; //para ir comprobando otras posiciones de 4 en 4
  }    


Código (java) [Seleccionar]
int getRandomNumber(){
    return 4; //chosen by fair dice roll
              //guaranteed to be random
}

redpeli20

En tu codigo, tu variable num cual es??  0x86FC6 o 6?

Aca explico mejor, recibo un numero sin signo por ejemplo 25798 que en hexa seria 0x000064C6, y al lado recibo otro numero que es el que deseo sustituir en el hexa anteriro y cambiarlo por 0.

Es decir, si recibo 0x000064C6 6 la respuesta del programa debe ser donde esta el 6 cambiarlo por 0; 0x000004c0.

Si la entrada fuese 0x000064C6 4, donde este el 4 lo sustituyo por 0. 0x000060C6

0xFer

#3
ya lo he solucionado pero no sé si explicarte todo o cómo lo mejor es que te pongas a estudiar y practicar, y vienes aquí cuando ya tengas algo y no estes empezando desde cero
Código (java) [Seleccionar]
int getRandomNumber(){
    return 4; //chosen by fair dice roll
              //guaranteed to be random
}

Peregring-lk

Pues yo he intentado hacer una versión no iterativa (ni recursiva, claro), de éste algoritmo, con alguna cadena finita de operaciones binarias... y casi pierdo la cabeza.

Primero "duplicaba" la máscara (por ejemplo, 0x6) para que tuviera mismo ancho que el `unsigned` con el que me comparo (por ejemplo, 0x66666666), y luego realizaba el XOR con el número original.

Como el XOR lo que hace es filtrarte los bits diferentes, estuve intentando construir otra máscara con un AND (para obtener los bits "iguales"), y luego, con algún tipo de resta y AND entre ambas máscaras, conseguir que los bits que han superado ambos test, se "sumen" (que deben estar exclusivamente encerradas en las cuartetas que no sean 0x6), de modo que al aplicar ésta máscara final con el número original, solo se hagan a cero las cuartetas oportunas.

¡Pero no hay forma! Os reto a que lo intentéis (una versión no interativa de éste problema --excepto quizás para construir una máscara original). De verdad, me parece increíble que algo tan trivial sea tan escurridizo.


0xFer

El código que publiqué arriba resuelve el problema.

Un saludo
Código (java) [Seleccionar]
int getRandomNumber(){
    return 4; //chosen by fair dice roll
              //guaranteed to be random
}

Peregring-lk

Sí, lo sé. Pero estoy convencido de que debe haber una solución no iterativa al problema, y el no encontrarlo me está sacando de quicio, jeje. Cuando tenga más tiempo lo intentaré de nuevo.