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

 

 


Tema destacado: Trabajando con las ramas de git (tercera parte)


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


Desconectado Desconectado

Mensajes: 481

555-555-0199@example.com


Ver Perfil WWW
Imprimir bits de un objeto
« en: 18 Febrero 2015, 23:44 pm »

Hola quiero crear una función que recibe un void * y un size en bytes para imprimir desde esta posición los bits. Algo parecido a esto pero con cualquier objeto

Código
  1. void printBitsNumber(unsigned value){
  2. const int movement = 8 * sizeof(value) - 1;
  3. const unsigned mask = 1 << movement;
  4.  
  5. for (int i = 0; i < movement; i++){
  6. cout << (value & mask ? '1' : '0');
  7. value <<= 1;
  8. if ((i + 1) % 8 == 0)
  9. cout << ' ';
  10. }
  11. }
  12.  
15 = 00000000 00000000 00000000 0000111

Lo estoy intentando pero no me sale, alguna pista?

Saludos


En línea

eferion


Desconectado Desconectado

Mensajes: 1.248


Ver Perfil
Re: Imprimir bits de un objeto
« Respuesta #1 en: 19 Febrero 2015, 08:38 am »

¿Algo así?

Código
  1. #include <iostream>
  2.  
  3. class A
  4. {
  5.    int a;
  6.    int b;
  7.  
  8.  public:
  9.  
  10.    A( )
  11.      : a( 1 ), b( 2 )
  12.    { }
  13. };
  14.  
  15. void Imprime( void* ptr, size_t size )
  16. {
  17.  char* charPtr = static_cast< char* >( ptr );
  18.  
  19.  while( size-- > 0 )
  20.  {
  21.    char mask = 1;
  22.    do
  23.    {
  24.      std::cout << (*charPtr & mask ? '1' : '0');
  25.    } while( mask <<= 1 );
  26.  
  27.    std::cout << ' ';
  28.    ++charPtr;
  29.  }
  30. }
  31.  
  32. int main()
  33. {
  34.  A a;
  35.  
  36.  Imprime( &a, sizeof( a ) );
  37. }



Editado:

Después de pensarlo con un pelín más de tranquilidad... no hace falta pasar el size... basta con usar un template. Eso sí, debidamente especializado para poder manejar tanto punteros como referencias

Código
  1. #include <iostream>
  2. #include <type_traits>
  3.  
  4. class A
  5. {
  6.    int a;
  7.    int b;
  8.  
  9.  public:
  10.  
  11.    A( )
  12.      : a( 1 ), b( 2 )
  13.    { }
  14. };
  15.  
  16. template< typename T >
  17. typename std::enable_if< std::is_pointer< T >::value, void >::type Imprime( T ptr )
  18. {
  19.  std::cout << "Pointer version: ";
  20.  char* charPtr = reinterpret_cast< char* >( ptr );
  21.  size_t size = sizeof( typename std::remove_pointer< T >::type );
  22.  while( size-- > 0 )
  23.  {
  24.    char mask = 1;
  25.    do
  26.    {
  27.      std::cout << (*charPtr & mask ? '1' : '0');
  28.    } while( mask <<= 1 );
  29.  
  30.    std::cout << ' ';
  31.    ++charPtr;
  32.  }
  33. }
  34.  
  35. template< typename T >
  36. typename std::enable_if< !std::is_pointer< T >::value, void >::type Imprime( const T& value )
  37. {
  38.  std::cout << "Reference version: ";
  39.  const char* charPtr = reinterpret_cast< const char* >( &value );
  40.  size_t size = sizeof( T );
  41.  while( size-- > 0 )
  42.  {
  43.    char mask = 1;
  44.    do
  45.    {
  46.      std::cout << (*charPtr & mask ? '1' : '0');
  47.    } while( mask <<= 1 );
  48.  
  49.    std::cout << ' ';
  50.    ++charPtr;
  51.  }
  52. }
  53.  
  54. int main()
  55. {
  56.  A a;
  57.  
  58.  Imprime( &a );
  59.  std::cout << std::endl;
  60.  Imprime( a );
  61. }


« Última modificación: 19 Febrero 2015, 09:59 am por eferion » En línea

patilanz


Desconectado Desconectado

Mensajes: 481

555-555-0199@example.com


Ver Perfil WWW
Re: Imprimir bits de un objeto
« Respuesta #2 en: 19 Febrero 2015, 17:07 pm »

Era justo lo que quería. A partir de tu función hice esto:

Código
  1. #include <iostream>
  2. #include <type_traits>
  3.  
  4. using namespace std;
  5.  
  6. class test{
  7. public:
  8. __int8 t8;
  9. __int16 t16;
  10. //__int16 t216;
  11. //char hola[200];
  12. //int a;
  13. };
  14.  
  15. template <typename T>
  16. typename enable_if<::is_pointer<T>::value, void>::type printBytes(T p){
  17. char * ptr = (char*)(p);
  18.  
  19. //size2 y size son iguales
  20. size_t size2 = sizeof(*p);
  21. size_t size = sizeof(remove_pointer<T>::type);
  22.  
  23. while (size-- > 0){
  24. __int8 mask = 1;
  25. do{
  26. cout << (*ptr & mask? '1' : '0');
  27. } while (mask <<= 1);
  28. cout << ' ';
  29. ptr++;
  30. }
  31. }
  32.  
  33. template <typename T>
  34. typename enable_if<::is_pointer<T>::value, void>::type printBytesReverse(T p){
  35. char * ptr = (char*)p;
  36. size_t size = sizeof(*p);
  37. while (size-- > 0){
  38. int mask = 0x80; // 0b100000000 -> 128
  39. do{
  40. cout << ((*ptr) & mask ? '1' : '0');
  41. } while ((mask >>= 1) != 0);
  42. cout << ' ';
  43. *ptr++;
  44. }
  45. }
  46.  
  47. unsigned invert(unsigned byte){ //Funcion aparte para invertir bytes
  48. unsigned newByte = 0;
  49. int mask = 1;
  50. int mask2 = 0x80;
  51. do{
  52. if (byte & mask)
  53. newByte |= mask2;
  54. mask2 >>= 1;
  55. } while (mask <<= 1);
  56. return newByte;
  57. }
  58.  
  59.  
  60. int main(){
  61. test t;
  62. t.t8 = -1;
  63. int number = 200000;
  64. printBytes<int *>(&number);
  65. cout << endl;
  66. printBytesReverse<int*>(&number);
  67. getchar();
  68. return 0;
  69. }
  70.  

Porque utilizas reinterpret_cast y remove pointer ? Funciona igual con una conversión normal.
Al imprimir los bits con la función printBytes para la variable "t" me imprimie esto: 00000010 10110000 11000000 00000000
1 byte = __int8 t8
3 y 4 bytes = __int16 t16

Que pasa con el byte 2 ?? Lo tiene cada clase que creo pero no se que contiene.

Si la clase tiene algún puntero que apunta a un array creado con new al imprimir no se mostrara, cierto ? Solo aparecerá la dirección de memoria

Gracias
« Última modificación: 19 Febrero 2015, 17:10 pm por patilanz » En línea

eferion


Desconectado Desconectado

Mensajes: 1.248


Ver Perfil
Re: Imprimir bits de un objeto
« Respuesta #3 en: 19 Febrero 2015, 17:37 pm »

Utilizo reinterpret_cast porque detesto los cast a la usanza de C "int valor = (int)X;" y la conversión entre los dos tipos no tiene por qué ser compatible. En este caso, con reinterpret_cast le estoy diciendo al compilador algo del estilo "tranquilo que se lo que me hago, esta conversión es legal aunque no lo parezca".

remove_pointer es un template de type_trait y lo que hace es eliminar el puntero de la declaración del tipo. sizeof( T* ) va a devolver, normalmente, 4, ya que un puntero ocupa 4 bytes, sin embargo yo quiero calcular sizeof( T ). Y para hacer este último cálculo necesito eliminar el puntero de la declaración.

En cuanto al segundo byte, puede ser alineamiento provocado por tu compilador. Piensa que en una arquitectura de 32 bits, el procesador optimiza para que los datos entren en estos 32 bits, que es el tamaño normal con el que trabaja... si tu usas únicamente 24 bits, el compilador puede decidir desperdiciar los otros 8 para que el alineamiento sea perfecto.
En línea

patilanz


Desconectado Desconectado

Mensajes: 481

555-555-0199@example.com


Ver Perfil WWW
Re: Imprimir bits de un objeto
« Respuesta #4 en: 19 Febrero 2015, 23:26 pm »

A mi con sizeof(*T) me devolvía el size correcto. Si agregaba elementos para llegar a mas de 200 bytes sin usar remove_pointer se conseguía. Aunque no lo probé con referencias, ahora lo miro.

Si se usa una arquitectura de 64 bits si uso 24 bits si el compilador lo decide se perderían 40 o en los 64 funciona de otra forma ?

Lo demás me quedo claro gracias.
En línea

eferion


Desconectado Desconectado

Mensajes: 1.248


Ver Perfil
Re: Imprimir bits de un objeto
« Respuesta #5 en: 20 Febrero 2015, 07:43 am »

Si la arquitectura es de 64 bits, entonces 64 bits es la unidad mínima de datos, luego lo normal es que la memoria consumida por cualquier programa sea múltiplo de 64 bits
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines