elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: (TUTORIAL) Aprende a emular Sentinel Dongle By Yapis


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Operadores a nivel de bits (lenguaje C).
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: 1 [2] Ir Abajo Respuesta Imprimir
Autor Tema: Operadores a nivel de bits (lenguaje C).  (Leído 10,154 veces)
Yoel Alejandro

Desconectado Desconectado

Mensajes: 254



Ver Perfil WWW
Re: Operadores a nivel de bits (lenguaje C).
« Respuesta #10 en: 18 Marzo 2014, 22:14 pm »

Ok, creo NOMB2014 que la intención de la "máscara" en los programas anteriores era imprimir un número en binario (por eso putchar() que imprime carácter a carácter). Para que la explicación sea más sencill pondré un ejemplo con un char (un byte).

Si queremos imprimir en binario tenemos que escanear cada uno de sus bits e imprimir un '1' ó un '0' según el caso. Pongamos el ejemplo del numero:

num = 1000 1001

Entonces comenzamos con la máscara mask = 1000 0000 (0x80 en hexadecimal). Hacemos el AND binario entre el número y la máscara. Observa bien que la máscara tendrá un único bit en 1, los demás en 0. Si el AND binario da como resultado distinto de cero es porque el número original posee un '1' en la misma posición de la máscara. Así que el bit más significativo del número es '1':

num & mask = 1000 1001 & 1000 0000 = 1000 0000

Ahora seguimos recorriendo el número de izquierda a derecha, para ellos usamos la máscara mask = 0100 0000 (0x40 en hexadecimal). El resultado será '0', porque el número posee un bit '0' en la misma posición donde la máscara tiene su único 'bit 1':

num & mask = 1000 1001 & 0100 0010 = 0000 0000

Y así ya conoces el valor de los dos bits más significativos de num. Siguiendo con las máscaras 0010 0000,  0001 0000, etc., conocerás los demás bits.

Observa que las máscaras sucesivas se obtienen fácilmente empezando con 1000 0000 y rotando a la derecha tantas veces como uno menos que la cantidad total de dígitos binarios que posea el número.

Así, un programa para imprimir en binario un número char sería, donde por sencillez sustituyo el operador ternario "?:" por un "if" estándar:
Código
  1. void imprimir(unsigned char num)
  2. {
  3. unsigned char mask = 0x80; /* la mascara */
  4. size_t i;
  5.  
  6. for (i = 0; i < sizeof(char) * CHAR_BIT; i++) {
  7. if ( num & mask )
  8. putchar('1');
  9. else
  10. putchar('0');
  11. mask >>= 1;
  12. }
  13. }
  14.  

=============
OBSERVACIONES: 1. Una forma de inicializar la máscara hubiera sido mask = 0x01 << 7, o sea agarrar el 0x01 y rodar el '1' a la izquierda 7 veces. O más consistentemente, mask = 1 << sizeof(char) * CHAR_BIT - 1. Digo que la segunda forma es más consistente, porque se puede cambiar fácilmente el tipo char por short int, o por int donde el tamaño del número en bits es determinado automáticamente por el compilador en lugar de hacerlo nosotros manualmente.

2. El importante el tipo de la máscara como "unsigned". Pues según las especificaciones para enteros signados negativos el comportamiento de la operación ">>" queda indeterminado. Los bits desplazados en la parte izquierda del número pudieran ser rellenados por '1', o por '0' dependiendo del sistema.


En línea

Saludos, Yoel.
P.D..-   Para mayores dudas, puedes enviarme un mensaje personal (M.P.)
NOB2014


Desconectado Desconectado

Mensajes: 366



Ver Perfil
Re: Operadores a nivel de bits (lenguaje C).
« Respuesta #11 en: 19 Marzo 2014, 13:59 pm »

Hola a todos.
Como siempre en este foro la ayuda es muy abundante y esmerada, con los últimos 2 post me queda bien claro como imprimir un número en binario, que es en definitiva lo que quería aprender.-
En definitiva voy a tratar de interpretar el código de rir3760, voy a correrlo, pero de principio no entiendo que valores arrojan size_t i y size_t j  y para que el doble for, ya me pongo a buscar información.-

Saludos.
Daniel


En línea

abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
Yoel Alejandro

Desconectado Desconectado

Mensajes: 254



Ver Perfil WWW
Re: Operadores a nivel de bits (lenguaje C).
« Respuesta #12 en: 20 Marzo 2014, 15:10 pm »

Para abreviarte un poco el trabajo, lo que rir3760 es un doble "for" anidado para imprimir el número en grupos de a 8 bits (o sea, bytes), con un espacio entre cada byte, e.g.:

11000001 00010011 10100110 00010111

El for con el contador "j" imprime cada octeto y el for con el contador "i" pasa de un octeto a otro. Mira que la instrucción sizeof(unsigned) te da el tamaño de un unsigned (que es el mismo tamaño del int) en bytes, que es 4 para el caso de una máquina con enteros de 32 bits. Este es el rango de i. Luego, la macro CHAR_BIT da el número de bits que ocupa un byte, o sea 8 en nuestro caso. Este es el rango de j.

De no haber usado este anidamiento el número se hubiera impreso con todos los bits "pegados", o sea, menos estéticamente. Otra solución, con un solo contador, tal vez hubiera sido intercalar un espacio luego del bit 7, luego del bit, 15, y luego del 23, con el operador módulo "%". Si el número más 1 es divisible por 8, dejar el espacio:
Código
  1. void imprimir(unsigned num)
  2. {
  3.  unsigned msb = 1U << sizeof(unsigned) * CHAR_BIT - 1;
  4.  size_t i;
  5.  size_t j;
  6.  
  7.  for (i = 0; i < sizeof(unsigned) * CHAR_BIT; i++){
  8.     putchar(num & msb ? '1' : '0');
  9.     msb >>= 1;
  10.  
  11.     /* aqui el espacio */
  12.     if ( i > 0 && (i + 1)%8 == 0 )
  13.        putchar(' ');
  14.  }
  15.  putchar('\n');
  16. }
  17.  
donde la condición i > 0 es para que no imprima espacio antes del bit número cero (el primero).

Por último, el tipo size_t es un tipo aritmético, normalmente un entero no signado, devuelto por el operador sizeof() y usado en funciones como strlen(), fread(), etc. Para decirlo de un modo sencillo, usamos ese tipo para enumerar cantidades "posiblemente grandes" de bytes. En el caso de rir3760 se definió "i" de tipo size_t porque ese es el tipo devuelto por la expresión sizeof(unsigned).

Se que dijiste que ibas a investigar todo esto, y deseo que lo hagas pero no me costaba nada dedicar 5 minutos a aclarar unas cosas que te hubieran demandado quiźa 2 horas (y así usas esas 2 horas en investigar otros temas  ;D).
En línea

Saludos, Yoel.
P.D..-   Para mayores dudas, puedes enviarme un mensaje personal (M.P.)
eferion


Desconectado Desconectado

Mensajes: 1.248


Ver Perfil
Re: Operadores a nivel de bits (lenguaje C).
« Respuesta #13 en: 20 Marzo 2014, 15:33 pm »

Código
  1. if ( i > 0 && (i + 1)%8 == 0 )

O más sencillo.

Código
  1. if ((i + 1)%8 == 0 )

Todo i en el rango ( 0..31 ) que verifica "(i+1)%8==0" es necesariamente mayor que 0, puesto que (0+1)%8 == 1%8 == 1 != 0.

;)
En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: Operadores a nivel de bits (lenguaje C).
« Respuesta #14 en: 20 Marzo 2014, 17:20 pm »

de principio no entiendo que valores arrojan size_t i y size_t j  y para que el doble for
Eso ya lo explico de una forma mas que satisfactoria yoel_alejandro.

----

En cuanto al condicional:
Código
  1. if ( i > 0 && (i + 1)%8 == 0 )
eferion ya indico como acortarlo, solo agregar que (por consistencia) se debe utilizar la macro CHAR_BIT:
Código
  1. if ((i + 1) % CHAR_BIT == 0) ...

Un saludo
En línea

C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language
NOB2014


Desconectado Desconectado

Mensajes: 366



Ver Perfil
Re: Operadores a nivel de bits (lenguaje C).
« Respuesta #15 en: 20 Marzo 2014, 20:39 pm »

Hola a todos.
Citar
Se que dijiste que ibas a investigar todo esto, y deseo que lo hagas pero no me costaba nada dedicar 5 minutos a aclarar unas cosas que te hubieran demandado quiźa 2 horas (y así usas esas 2 horas en investigar otros temas  ;D
No te das una idea lo que se estima estas frases cuando uno tiene 62 años y a nadie al alcance para pedir ayuda, lo digo más que nada por la seguridad que brinda el hecho de saber que podes levantar el tubo y tener la respuesta a tú duda o mandar un mail y del otro lado contar con un amigo que tiene todas las respuestas a tus inquietudes, bueno por algo será, por lo menos cuento con Uds.-
Gracias eferion y a vos rir3760 por la participación, en cuanto a este tema para mí lo podemos dar por solucionado.-

Saludos.
Daniel

En línea

abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
Yoel Alejandro

Desconectado Desconectado

Mensajes: 254



Ver Perfil WWW
Re: Operadores a nivel de bits (lenguaje C).
« Respuesta #16 en: 21 Marzo 2014, 15:16 pm »

Correcto!
En línea

Saludos, Yoel.
P.D..-   Para mayores dudas, puedes enviarme un mensaje personal (M.P.)
Páginas: 1 [2] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Ayuda, operadores a nivel bit?
PHP
HardieVon 3 2,558 Último mensaje 19 Febrero 2009, 05:55 am
por HardieVon
[Python] Duda de Operadores a nivel bit [Not(~)]
Scripting
evocal 1 4,306 Último mensaje 25 Noviembre 2012, 00:03 am
por Danyfirex
De minúscula a mayúscula a nivel de bits en lenguaje C. « 1 2 3 4 »
Programación C/C++
DanielPy 32 17,185 Último mensaje 4 Enero 2014, 19:12 pm
por leosansan
De minúscula a mayúscula a nivel de bits (lenguaje C.)
Programación C/C++
NOB2014 4 3,918 Último mensaje 21 Marzo 2014, 02:44 am
por rir3760
Los operadores podrán bloquear el nivel de cobertura en Android P
Noticias
wolfbcn 1 1,799 Último mensaje 25 Diciembre 2017, 23:31 pm
por Serapis
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines