fbpx

Expresate

Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:

Descomponer un doub...
 
Avisos
Vaciar todo

Descomponer un double en 4 bytes

9 Respuestas
5 Usuarios
0 Reactions
4,253 Visitas
choda
Respuestas: 7
Topic starter
(@choda)
Active Member
Registrado: hace 17 años

Hola a todos!!!

Bien, la cosa, a priori, es bien fácil. Todos sabemos que un "double" son 32 bits (4 bytes), y a mi me interesa para mi proyecto almacenar en 4 bytes (de tipo char) cada uno de los 4 bytes del double.

He probado con punteros, pero no hay manera de hacerlo funcionar... alguien podría echar una mano?

SALUDOS!!!!! y gracias 😉

Responder
8 respuestas
roboticsbcn
Respuestas: 244
(@roboticsbcn)
Estimable Member
Registrado: hace 19 años

personalmente la que te debería funcionar SEGURo es la que pone eventronic. De todas maneras deberías ver como se comporta tu compilador para ver como almacena una variable del tipo long en memoria.
Este trozo de código debería obtener en la variable kk el valor 0x78 correspondiente el byte menos significativo del long.

Posteriormente deberías recorrer una posición arriba o abajo (dependiendo del compilador) para conseguir los otros bytes.

unsigned long lon;
unsigned char kk;
unsigned long *ptr;

lon=0x12345678;
ptr=&lon;
kk=*ptr;

No tengo ni idea que como de rápido se ejecuta este código, pero creo que es la manera correcta de hacerlo. Corregirme si me equivoco.

Salu2!

Responder
choda
Respuestas: 7
Topic starter
(@choda)
Active Member
Registrado: hace 17 años

Hola

Otra forma de hacerlo:


unsigned char a, b, c , d;
double f;

a = (unsigned char) f; //toma el byte de menos peso
f = f >> 8; //corro 8 bits a la derecha, para coger el siguiente byte
b = (unsigned char) f; //toma el byte de menos peso
f = f >> 8; //corro 8 bits a la derecha
c = (unsigned char) f; //toma el byte de menos peso
f = f >> 8; //corro 8 bits a la derecha
d = (unsigned char) f; //toma el byte de menos peso

se puede simplificar más, pero así es más claro. No lo he probado tal cual, pero debería funcionar.
Salu2

Esa fue la primera forma en que pensé..... pero hay dos problemas:

1) a = (unsigned char) f; No almacena el LSB tal como lo tengo, si no que hace una conversión implicita, por lo que se "adapta" el número float a su nuevo 'entorno' char.
2) f = f >> 8; No sé porqué, esto no se lo traga de ninguna de las maneras el compilador....

Ya probé a ver en que direcciones de memoria se guarda el double (o float) para ver exactamente que hay. Os ilustro con un ejemplo:

float en posición 0x205: 35 C0 F1 5A

Una vez hecho 'a = (unsigned char) f;' miro la dirección de memoria de a, que es 0x201 y me encuentro en ésta posición con el valor 7F. Por lo tanto, este método no es del todo bueno....

Voy a probar ahora usar una unión, a ver que tal 😉

SALUDOS

Responder
choda
Respuestas: 7
Topic starter
(@choda)
Active Member
Registrado: hace 17 años

Me autorespondo ^^

Bien, lo logré por fin. El camino correcto era seguir una "union" como bien dijo Ranganok. Os poseteo aquí la forma de hacerlo 😉

char a, b, c, d;
union _float {
char a[4];
float f; } miFloat;

miFloat.f = 34023402390482390.3490908423422; // 0x5AF1C035 (de prueba)
// Se almacenan de forma inversa, es decir: 0x35 0xC0 0xF1 0x5A

a = miFloat.a[0];
b = miFloat.a[1];
c = miFloat.a[2];
d = miFloat.a[3];

// Sacamos por pantalla
printf( "La dirección de miFloat.f es %x n", &miFloat.f );
printf( "a es %x n", a ); // 0x35
printf( "b es %x n", b ); // 0xC0
printf( "c es %x n", c ); // 0xF1
printf( "d es %x n", d ); // 0x5A

Imprimiendose por consola los resultados que deseamos 🙂

Gracias a todos por vuestra ayuda, y sigamos generando tan grandiosa y valiosisima documentación!!! ^^

Un saludo.

Responder
roboticsbcn
Respuestas: 244
(@roboticsbcn)
Estimable Member
Registrado: hace 19 años

choda, tienes razón...

En la operación a = (unsigned char) f falta capar los bytes q no te interesan haciendo... a = (unsigned char) ( f & 0x000000FF)

Lo de desplazar bytes no tengo ni idea pq no te gunciona.

Me ha gustado lo del union, nunca lo había usado 🙂

Responder
Página 2 / 2
Compartir: