Estudiando función que convierte a mayúscula un carácter con operadores de bit

Iniciado por kutcher, 30 Junio 2014, 17:46 PM

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

kutcher

Hi la función en cuestión es esta:

Código (cpp) [Seleccionar]
void upper_case(char *src)
{
   while (*src != '\0')
   {
       if (islower(*src))
  *src = (*src & ~0x20);
       src++;
   }
}


No logro entender esta linea del código:

Código (cpp) [Seleccionar]
*src = (*src & ~0x20);

Se que el operador ~ invierte cada bit del 0x20 (i.e 32) convirtiéndolo al numero binario -11111 == -31. Supongamos que *src = 'a' al aplicar el operador &

Código (asm) [Seleccionar]
1100001
-0011111
_______
0000001


El resultado no es lo esperado que seria el binario 1000001 == 65 alguien podría explicarme que pasa aquí o acaso al usar el operador & sobre binarios negativos tiene otro efecto..

Eternal Idol

~0x20 = 0xDF = -33 = 1101 1111

'a' = 0x61 = 97 = 110 0001

1101 1111
&
0110 0001
---------------
0100 0001 = 0x41 = 65 = 'A'
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

kutcher

@Eternal Idol gracias por tu respuesta, solo una consulta mas porque es necesario invertir los bits de 0x20

Eternal Idol

No es necesario en lo absoluto, es una forma de hacerlo, una resta de 0x20=32 a la letra en minuscula tambien daria el resultado esperado.

Mira la tabla ASCII:
http://www.asciitable.com/
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

kutcher

Cita de: Eternal Idol en 30 Junio 2014, 19:54 PM
No es necesario en lo absoluto, es una forma de hacerlo, una resta de 0x20=32 a la letra en minuscula tambien daria el resultado esperado.

Excelente mas claro ni el agua xD, tema resuelto

Eternal Idol

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

kutcher

Solo a modo de complemento al tema, quisiera añadir estos puntos de vista:

Analizando mas a fondo el código me he dado cuenta que los carácteres (A-Z) y (a-z ) todos los bits de estos son respectivamente iguales, excepto el sexto bit (contando desde la derecha)

a = 1100001     A = 1000001
b = 1100010     B = 1000010
c = 1100011     C = 1000011
d = 1100100     D = 1000100

Como pueden ver las minúsculas tienen el sexto bit a 1 y las mayúsculas a 0 en consecuencia al aplicarle el operador & con la mascara de bit apropiada logramos apagar el sexto bit y dejar los demás intactos obteniendo así su equivalente en mayúscula

1101 1111   <== Mascara de bit
&
0110 0001   <== a en binario
------------
0100 0001   <== A en binario


Eternal Idol

Otra manera mas entonces, si sabemos que 0x20 = 32 = 10 0000 (en negrita el bit necesario), haciendo un XOR sobre el caracter en minuscula obtenemos el caracter en mayuscula:

97 ^ 32 = 65;

0110 0001
^
0010 0000
--------------
0100 0001

http://en.wikipedia.org/wiki/Exclusive_or

Si volvemos a aplicar la mascara:
65 ^ 32 = 97;

0100 0001
^
0010 0000
--------------
0110 0001


De esta manera tenes una funcion capaz de cambiar el case (de minuscula a mayuscula y viceversa).
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

kutcher

Cita de: Eternal Idol en  1 Julio 2014, 09:31 AM
De esta manera tenes una funcion capaz de cambiar el case (de minuscula a mayuscula y viceversa).

Wow.. interesante forma de hacerlo por lo versátil que es, ahora mismo lo pruebo a ver que tal