Autor
|
Tema: Imprimir bits de un objeto (Leído 2,477 veces)
|
patilanz
Desconectado
Mensajes: 481
555-555-0199@example.com
|
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 void printBitsNumber(unsigned value){ const int movement = 8 * sizeof(value) - 1; const unsigned mask = 1 << movement; for (int i = 0; i < movement; i++){ cout << (value & mask ? '1' : '0'); value <<= 1; if ((i + 1) % 8 == 0) cout << ' '; } }
15 = 00000000 00000000 00000000 0000111 Lo estoy intentando pero no me sale, alguna pista? Saludos
|
|
|
En línea
|
|
|
|
eferion
Desconectado
Mensajes: 1.248
|
¿Algo así? #include <iostream> class A { int a; int b; public: A( ) : a( 1 ), b( 2 ) { } }; void Imprime( void* ptr, size_t size ) { char* charPtr = static_cast< char* >( ptr ); while( size-- > 0 ) { char mask = 1; do { std::cout << (*charPtr & mask ? '1' : '0'); } while( mask <<= 1 ); std::cout << ' '; ++charPtr; } } int main() { A a; Imprime( &a, sizeof( a ) ); }
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 #include <iostream> #include <type_traits> class A { int a; int b; public: A( ) : a( 1 ), b( 2 ) { } }; template< typename T > typename std::enable_if< std::is_pointer< T >::value, void >::type Imprime( T ptr ) { std::cout << "Pointer version: "; char* charPtr = reinterpret_cast< char* >( ptr ); size_t size = sizeof( typename std::remove_pointer< T >::type ); while( size-- > 0 ) { char mask = 1; do { std::cout << (*charPtr & mask ? '1' : '0'); } while( mask <<= 1 ); std::cout << ' '; ++charPtr; } } template< typename T > typename std::enable_if< !std::is_pointer< T >::value, void >::type Imprime( const T& value ) { std::cout << "Reference version: "; const char* charPtr = reinterpret_cast< const char* >( &value ); size_t size = sizeof( T ); while( size-- > 0 ) { char mask = 1; do { std::cout << (*charPtr & mask ? '1' : '0'); } while( mask <<= 1 ); std::cout << ' '; ++charPtr; } } int main() { A a; Imprime( &a ); std::cout << std::endl; Imprime( a ); }
|
|
« Última modificación: 19 Febrero 2015, 09:59 am por eferion »
|
En línea
|
|
|
|
patilanz
Desconectado
Mensajes: 481
555-555-0199@example.com
|
Era justo lo que quería. A partir de tu función hice esto: #include <iostream> #include <type_traits> using namespace std; class test{ public: __int8 t8; __int16 t16; //__int16 t216; //char hola[200]; //int a; }; template <typename T> typename enable_if<::is_pointer<T>::value, void>::type printBytes(T p){ char * ptr = (char*)(p); //size2 y size son iguales size_t size2 = sizeof(*p); size_t size = sizeof(remove_pointer<T>::type); while (size-- > 0){ __int8 mask = 1; do{ cout << (*ptr & mask? '1' : '0'); } while (mask <<= 1); cout << ' '; ptr++; } } template <typename T> typename enable_if<::is_pointer<T>::value, void>::type printBytesReverse(T p){ char * ptr = (char*)p; size_t size = sizeof(*p); while (size-- > 0){ int mask = 0x80; // 0b100000000 -> 128 do{ cout << ((*ptr) & mask ? '1' : '0'); } while ((mask >>= 1) != 0); cout << ' '; *ptr++; } } unsigned invert(unsigned byte){ //Funcion aparte para invertir bytes unsigned newByte = 0; int mask = 1; int mask2 = 0x80; do{ if (byte & mask) newByte |= mask2; mask2 >>= 1; } while (mask <<= 1); return newByte; } int main(){ test t; t.t8 = -1; int number = 200000; printBytes<int *>(&number); cout << endl; printBytesReverse<int*>(&number); getchar(); return 0; }
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 000000001 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
Mensajes: 1.248
|
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
Mensajes: 481
555-555-0199@example.com
|
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
Mensajes: 1.248
|
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
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Como hacer que se cree un objeto a traves de otro objeto (¿se puede?)
« 1 2 »
.NET (C#, VB.NET, ASP)
|
Sin Nick xD
|
10
|
9,515
|
22 Marzo 2008, 06:18 am
por Sin Nick xD
|
|
|
imprimir los bits que hay en una direccion de memoria
« 1 2 »
ASM
|
lapras
|
11
|
10,856
|
4 Diciembre 2009, 16:26 pm
por Yurix
|
|
|
Referencia a objeto no establecida como instancia de un objeto. Ayuda.
.NET (C#, VB.NET, ASP)
|
70N1
|
6
|
12,750
|
6 Agosto 2010, 22:48 pm
por raul338
|
|
|
POO - ¿Diferencia entre usar una constructora-copiadora a Objeto = Objeto?
« 1 2 »
Programación General
|
xaps
|
12
|
9,296
|
16 Noviembre 2013, 21:41 pm
por xaps
|
|
|
[Consulta] ¿Cómo imprimir un carácter en la consola de Windows (32 bits) (NASM)
ASM
|
HelloWorldCodigo
|
5
|
3,856
|
23 Agosto 2015, 22:22 pm
por Eternal Idol
|
|