Discussion:
Campos de bit
(demasiado antiguo para responder)
lestat_l
2006-01-23 11:08:01 UTC
Permalink
Hola a todos:

Tengo un pequeño problema con campos de bit. El caso es que necesito
que en un archivo se guarden datos con un número específico de bits,
y para ello pensé utilizar los campos de bit, que me parecieron una
alternativa más lógica que hacer desplazamientos y máscaras para
conseguir poner los valores adecuados.

Definí la estructura, e hice la prueba con algunos valores. Así, los
escribe en un archivo, luego lee del archivo, y me los muestra en
pantalla. Perfecto.

Sin embargo, y dado que luego ese archivo tendrá que tratarlo otra
aplicación, me puse a curiosear en el archivo que se había creado. El
resultado fue que no coincidía con lo que tendría que ser, con lo que
me surgen varias dudas:

- ¿Cómo se almacenan estos campos de bit realmente?
- ¿Por qué, si inicializo los campos a 0, no guarda ceros en el
archivo, en las posiciones donde no he escrito otra cosa?

El código es el siguiente:

bits.h:

#ifndef _BITS_
#define _BITS_

typedef struct sPrincipal{
unsigned int total:8;
unsigned int ano:7;
unsigned int tiempo:20;
unsigned int seD:8;
unsigned int numSat:4;
unsigned int edadP:1;
signed int latitud:32;
signed int longitud:32;
unsigned int velocidad:6;
unsigned int ignicion:1;
unsigned int movimiento:1;
unsigned int distancia:23;
} tipoPrincipal;

typedef struct sIncremental{
unsigned int incTiempo:11;
unsigned int seD:8;
unsigned int numSat:4;
unsigned int edadP:1;
signed int incLatitud:18;
signed int incLongitud:18;
unsigned int velocidad:6;
unsigned int ignicion:1;
unsigned int movimiento:1;
unsigned int incDistancia:16;
} tipoIncremental;

typedef struct sRegHco{
tipoPrincipal Principal;
tipoIncremental Incremental[15];
} tipoRegHco;

void copiarEstructura(tipoRegHco,tipoRegHco *);
void inicializarEstructura(tipoRegHco *);

#endif

bits.cpp:

#include "bits.h"

void copiarEstructura(tipoRegHco reg1,tipoRegHco *reg2){
(*reg2).Principal.total=reg1.Principal.total;
(*reg2).Principal.ano=reg1.Principal.ano;
(*reg2).Principal.tiempo=reg1.Principal.tiempo;
(*reg2).Principal.seD=reg1.Principal.seD;
(*reg2).Principal.numSat=reg1.Principal.numSat;
(*reg2).Principal.edadP=reg1.Principal.edadP;
(*reg2).Principal.latitud=reg1.Principal.latitud;
(*reg2).Principal.longitud=reg1.Principal.longitud;
(*reg2).Principal.velocidad=reg1.Principal.velocidad;
(*reg2).Principal.ignicion=reg1.Principal.ignicion;
(*reg2).Principal.movimiento=reg1.Principal.movimiento;
(*reg2).Principal.distancia=reg1.Principal.distancia;

for(short i=0;i<15;i++){
(*reg2).Incremental[i].incTiempo=reg1.Incremental[i].incTiempo;
(*reg2).Incremental[i].seD=reg1.Incremental[i].seD;
(*reg2).Incremental[i].numSat=reg1.Incremental[i].numSat;
(*reg2).Incremental[i].edadP=reg1.Incremental[i].edadP;
(*reg2).Incremental[i].incLatitud=reg1.Incremental[i].incLatitud;
(*reg2).Incremental[i].incLongitud=reg1.Incremental[i].incLongitud;
(*reg2).Incremental[i].velocidad=reg1.Incremental[i].velocidad;
(*reg2).Incremental[i].ignicion=reg1.Incremental[i].ignicion;
(*reg2).Incremental[i].movimiento=reg1.Incremental[i].movimiento;
(*reg2).Incremental[i].incDistancia=reg1.Incremental[i].incDistancia;
}
}

void inicializarEstructura(tipoRegHco *reg){
(*reg).Principal.total=0;
(*reg).Principal.ano=0;
(*reg).Principal.tiempo=0;
(*reg).Principal.seD=0;
(*reg).Principal.numSat=0;
(*reg).Principal.edadP=0;
(*reg).Principal.latitud=0;
(*reg).Principal.longitud=0;
(*reg).Principal.velocidad=0;
(*reg).Principal.ignicion=0;
(*reg).Principal.movimiento=0;
(*reg).Principal.distancia=0;

for(short i=0;i<15;i++){
(*reg).Incremental[i].incTiempo=0;
(*reg).Incremental[i].seD=0;
(*reg).Incremental[i].numSat=0;
(*reg).Incremental[i].edadP=0;
(*reg).Incremental[i].incLatitud=0;
(*reg).Incremental[i].incLongitud=0;
(*reg).Incremental[i].velocidad=0;
(*reg).Incremental[i].ignicion=0;
(*reg).Incremental[i].movimiento=0;
(*reg).Incremental[i].incDistancia=0;
}
}

pruebaBits.cpp:

#include <stdio.h>
#include <stdlib.h>
#include "bits.h"

FILE *fichero;
size_t tamano;
tipoRegHco Registro;
tipoRegHco *RegGuardar=NULL;
tipoRegHco RegHco[744];

int main(int argc, char* argv[])
{
for(int i=0;i<744;i++){
inicializarEstructura(&RegHco[i]);
}

RegHco[0].Principal.total=2;
RegHco[0].Principal.ano=26;
RegHco[0].Principal.tiempo=3;
RegHco[0].Principal.seD=0;
RegHco[0].Principal.numSat=3;
RegHco[0].Principal.edadP=1;
RegHco[0].Principal.latitud=4234567;
RegHco[0].Principal.longitud=-365432;
RegHco[0].Principal.velocidad=60;
RegHco[0].Principal.ignicion=1;
RegHco[0].Principal.movimiento=0;
RegHco[0].Principal.distancia=100;
RegHco[0].Incremental[0].incTiempo=1000;
RegHco[0].Incremental[0].seD=0;
RegHco[0].Incremental[0].numSat=10;
RegHco[0].Incremental[0].edadP=1;
RegHco[0].Incremental[0].incLatitud=-1000;
RegHco[0].Incremental[0].incLongitud=1000;
RegHco[0].Incremental[0].velocidad=62;
RegHco[0].Incremental[0].ignicion=0;
RegHco[0].Incremental[0].movimiento=1;
RegHco[0].Incremental[0].incDistancia=1000;

RegGuardar=new struct sRegHco[1];

//RegGuardar[0]=RegHco[0];
/* RegGuardar[0].Principal.total=RegHco[0].Principal.total;
RegGuardar[0].Principal.ano=RegHco[0].Principal.ano;
RegGuardar[0].Principal.tiempo=RegHco[0].Principal.tiempo;
RegGuardar[0].Principal.seD=RegHco[0].Principal.seD;
RegGuardar[0].Principal.numSat=RegHco[0].Principal.numSat;
RegGuardar[0].Principal.edadP=RegHco[0].Principal.edadP;
RegGuardar[0].Principal.latitud=RegHco[0].Principal.latitud;
RegGuardar[0].Principal.longitud=RegHco[0].Principal.longitud;
RegGuardar[0].Principal.velocidad=RegHco[0].Principal.velocidad;
RegGuardar[0].Principal.ignicion=RegHco[0].Principal.ignicion;
RegGuardar[0].Principal.movimiento=RegHco[0].Principal.movimiento;
RegGuardar[0].Principal.distancia=RegHco[0].Principal.distancia;
RegGuardar[0].Incremental[0].incTiempo=RegHco[0].Incremental[0].incTiempo;
RegGuardar[0].Incremental[0].seD=RegHco[0].Incremental[0].seD;
RegGuardar[0].Incremental[0].numSat=RegHco[0].Incremental[0].numSat;
RegGuardar[0].Incremental[0].edadP=RegHco[0].Incremental[0].edadP;
RegGuardar[0].Incremental[0].incLatitud=RegHco[0].Incremental[0].incLatitud;
RegGuardar[0].Incremental[0].incLongitud=RegHco[0].Incremental[0].incLongitud;
RegGuardar[0].Incremental[0].velocidad=RegHco[0].Incremental[0].velocidad;
RegGuardar[0].Incremental[0].ignicion=RegHco[0].Incremental[0].ignicion;
RegGuardar[0].Incremental[0].movimiento=RegHco[0].Incremental[0].movimiento;
RegGuardar[0].Incremental[0].incDistancia=RegHco[0].Incremental[0].incDistancia;*/

copiarEstructura(RegHco[0],&RegGuardar[0]);

fichero=fopen("pruebaBits.dat", "w+b");
tamano=fwrite(RegGuardar,sizeof(*RegGuardar),1,fichero),
fclose(fichero);
printf("El tamaño es: %d\n",tamano);

delete(RegGuardar);

fichero=fopen("pruebabits.dat","rb");
tamano=fread(&Registro,sizeof(Registro),1,fichero);
fclose(fichero);
printf("El tamaño leído es: %d\n",tamano);

printf("Total: %d\n",Registro.Principal.total);
printf("Año: %d\n",Registro.Principal.ano);
printf("Tiempo: %d\n",Registro.Principal.tiempo);
printf("Distancia: %d\n",Registro.Principal.distancia);
printf("Latitud y Longitud: %d,
%d\n",Registro.Principal.latitud,Registro.Principal.longitud);
printf("incTiempo: %d\n",Registro.Incremental[0].incTiempo);
printf("incDistancia: %d\n",Registro.Incremental[0].incDistancia);
printf("incLatitud e incLongitud: %d,
%d\n",Registro.Incremental[0].incLatitud,Registro.Incremental[0].incLongitud);

return 0;
}

El archivo que se crea es el siguiente:

0000000: 029a cdcd 0300 0030 cdcd cdcd 479d 4000 ***@.
0000010: 886c faff 7c64 0080 e803 d0cd 18fc cfcd .l..|d..........
0000020: e803 f8ce e803 cdcd 0000 00cd 0000 cccd ................
0000030: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................
0000040: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................
0000050: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................
0000060: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................
0000070: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................
0000080: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................
0000090: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................
00000a0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................
00000b0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................
00000c0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................
00000d0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................
00000e0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................
00000f0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................
0000100: 0000 00cc 0000 cdcd 0d0a ..........

Que, traducido a binario, si no me he equivocado, sería:

00000010100110101100110111001101000000110000000000000000001100001100110111001101110011011100110101000111100111010100000000000000
10001000011011001111101011111111011111000110010000000000100000001110100000000011110100001100110100011000111111001100111111001101
11101000000000111111100011001110111010000000001111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011010000110100001010

Sin embargo, para los valores que le doy, se supone que la primera
línea debería ser (igualmente, si no me he equivocado):

00000010001101000000000000000000011000000000011100000000010000001001110101000111100000000000010110010011011110001111001000000000000000001100100

Cosa que no coincide. De ahí, mis dudas. Espero que podáis ayudarme.

Un saludo y muchas gracias.
Carlos Martinez Garcia
2006-01-24 07:55:47 UTC
Permalink
Hola lestat_l:

No he probado el programa porque no dispongo de mucho tiempo, pero yo
diría que estás presuponiendo cómo debe ser la representación de la
clase por parte de tu compilador y eso no es una postura correcta.
La disposición en memoria de los atributos no está estipulada y
dependerá de tu entorno, así como la representación en memoria de los
valores de tales atributos depende del entorno de ejecución.

Entiendo que estás presuponiendo que el compilador asigna el número
especificado de bits por cada campo y luego pone uno tras otro.
Yo creo que no es así, sino que por cuestión de la arquitectura de tu
máquina, asigna en bloques de byte.
Con lo que si tu tienes un campo del tipo:
campo1:8
Te ocupa 8 bits
Pero si tienes un campo del tipo:
campo2:7
Te ocupa también 8 bits
Y si tienes un campo del tipo:
campo3:20
Te ocupa 24 bits

Por lo que veo en el resultado, los valores parecen ajustados a la
derecha en tal representación.
Otra pregunta sería: ¿que hace con los bits sobrantes?
A mi me parece que su valor es indefinido (lo que hubiera en memoria en
el momento de la asignación). Creo que es basura y que simplemente no lo
trata (descarta esos bits sobrantes).

La razón de que sean múltiplos de 8 en tu plataforma, o de 16, 32, 64
(en otras), es cuestión de eficiencia, porque de lo contrario, por cada
operación de asignación que hicieras, tendría que hacer el ordenador lo
que tu no haces (aplicar máscaras, etc...), y es mucho más rápido,
almacenarlo en bloques de tamaño que maneje el ordenador.

Un saludo.

Espero que te haya sido de ayuda
Post by lestat_l
Tengo un pequeño problema con campos de bit. El caso es que necesito
que en un archivo se guarden datos con un número específico de bits,
y para ello pensé utilizar los campos de bit, que me parecieron una
alternativa más lógica que hacer desplazamientos y máscaras para
conseguir poner los valores adecuados.
Definí la estructura, e hice la prueba con algunos valores. Así, los
escribe en un archivo, luego lee del archivo, y me los muestra en
pantalla. Perfecto.
Sin embargo, y dado que luego ese archivo tendrá que tratarlo otra
aplicación, me puse a curiosear en el archivo que se había creado. El
resultado fue que no coincidía con lo que tendría que ser, con lo que
- ¿Cómo se almacenan estos campos de bit realmente?
- ¿Por qué, si inicializo los campos a 0, no guarda ceros en el
archivo, en las posiciones donde no he escrito otra cosa?
#ifndef _BITS_
#define _BITS_
typedef struct sPrincipal{
unsigned int total:8;
unsigned int ano:7;
unsigned int tiempo:20;
unsigned int seD:8;
unsigned int numSat:4;
unsigned int edadP:1;
signed int latitud:32;
signed int longitud:32;
unsigned int velocidad:6;
unsigned int ignicion:1;
unsigned int movimiento:1;
unsigned int distancia:23;
} tipoPrincipal;
typedef struct sIncremental{
unsigned int incTiempo:11;
unsigned int seD:8;
unsigned int numSat:4;
unsigned int edadP:1;
signed int incLatitud:18;
signed int incLongitud:18;
unsigned int velocidad:6;
unsigned int ignicion:1;
unsigned int movimiento:1;
unsigned int incDistancia:16;
} tipoIncremental;
typedef struct sRegHco{
tipoPrincipal Principal;
tipoIncremental Incremental[15];
} tipoRegHco;
void copiarEstructura(tipoRegHco,tipoRegHco *);
void inicializarEstructura(tipoRegHco *);
#endif
#include "bits.h"
void copiarEstructura(tipoRegHco reg1,tipoRegHco *reg2){
(*reg2).Principal.total=reg1.Principal.total;
(*reg2).Principal.ano=reg1.Principal.ano;
(*reg2).Principal.tiempo=reg1.Principal.tiempo;
(*reg2).Principal.seD=reg1.Principal.seD;
(*reg2).Principal.numSat=reg1.Principal.numSat;
(*reg2).Principal.edadP=reg1.Principal.edadP;
(*reg2).Principal.latitud=reg1.Principal.latitud;
(*reg2).Principal.longitud=reg1.Principal.longitud;
(*reg2).Principal.velocidad=reg1.Principal.velocidad;
(*reg2).Principal.ignicion=reg1.Principal.ignicion;
(*reg2).Principal.movimiento=reg1.Principal.movimiento;
(*reg2).Principal.distancia=reg1.Principal.distancia;
for(short i=0;i<15;i++){
(*reg2).Incremental[i].incTiempo=reg1.Incremental[i].incTiempo;
(*reg2).Incremental[i].seD=reg1.Incremental[i].seD;
(*reg2).Incremental[i].numSat=reg1.Incremental[i].numSat;
(*reg2).Incremental[i].edadP=reg1.Incremental[i].edadP;
(*reg2).Incremental[i].incLatitud=reg1.Incremental[i].incLatitud;
(*reg2).Incremental[i].incLongitud=reg1.Incremental[i].incLongitud;
(*reg2).Incremental[i].velocidad=reg1.Incremental[i].velocidad;
(*reg2).Incremental[i].ignicion=reg1.Incremental[i].ignicion;
(*reg2).Incremental[i].movimiento=reg1.Incremental[i].movimiento;
(*reg2).Incremental[i].incDistancia=reg1.Incremental[i].incDistancia;
}
}
void inicializarEstructura(tipoRegHco *reg){
(*reg).Principal.total=0;
(*reg).Principal.ano=0;
(*reg).Principal.tiempo=0;
(*reg).Principal.seD=0;
(*reg).Principal.numSat=0;
(*reg).Principal.edadP=0;
(*reg).Principal.latitud=0;
(*reg).Principal.longitud=0;
(*reg).Principal.velocidad=0;
(*reg).Principal.ignicion=0;
(*reg).Principal.movimiento=0;
(*reg).Principal.distancia=0;
for(short i=0;i<15;i++){
(*reg).Incremental[i].incTiempo=0;
(*reg).Incremental[i].seD=0;
(*reg).Incremental[i].numSat=0;
(*reg).Incremental[i].edadP=0;
(*reg).Incremental[i].incLatitud=0;
(*reg).Incremental[i].incLongitud=0;
(*reg).Incremental[i].velocidad=0;
(*reg).Incremental[i].ignicion=0;
(*reg).Incremental[i].movimiento=0;
(*reg).Incremental[i].incDistancia=0;
}
}
#include <stdio.h>
#include <stdlib.h>
#include "bits.h"
FILE *fichero;
size_t tamano;
tipoRegHco Registro;
tipoRegHco *RegGuardar=NULL;
tipoRegHco RegHco[744];
int main(int argc, char* argv[])
{
for(int i=0;i<744;i++){
inicializarEstructura(&RegHco[i]);
}
RegHco[0].Principal.total=2;
RegHco[0].Principal.ano=26;
RegHco[0].Principal.tiempo=3;
RegHco[0].Principal.seD=0;
RegHco[0].Principal.numSat=3;
RegHco[0].Principal.edadP=1;
RegHco[0].Principal.latitud=4234567;
RegHco[0].Principal.longitud=-365432;
RegHco[0].Principal.velocidad=60;
RegHco[0].Principal.ignicion=1;
RegHco[0].Principal.movimiento=0;
RegHco[0].Principal.distancia=100;
RegHco[0].Incremental[0].incTiempo=1000;
RegHco[0].Incremental[0].seD=0;
RegHco[0].Incremental[0].numSat=10;
RegHco[0].Incremental[0].edadP=1;
RegHco[0].Incremental[0].incLatitud=-1000;
RegHco[0].Incremental[0].incLongitud=1000;
RegHco[0].Incremental[0].velocidad=62;
RegHco[0].Incremental[0].ignicion=0;
RegHco[0].Incremental[0].movimiento=1;
RegHco[0].Incremental[0].incDistancia=1000;
RegGuardar=new struct sRegHco[1];
//RegGuardar[0]=RegHco[0];
/* RegGuardar[0].Principal.total=RegHco[0].Principal.total;
RegGuardar[0].Principal.ano=RegHco[0].Principal.ano;
RegGuardar[0].Principal.tiempo=RegHco[0].Principal.tiempo;
RegGuardar[0].Principal.seD=RegHco[0].Principal.seD;
RegGuardar[0].Principal.numSat=RegHco[0].Principal.numSat;
RegGuardar[0].Principal.edadP=RegHco[0].Principal.edadP;
RegGuardar[0].Principal.latitud=RegHco[0].Principal.latitud;
RegGuardar[0].Principal.longitud=RegHco[0].Principal.longitud;
RegGuardar[0].Principal.velocidad=RegHco[0].Principal.velocidad;
RegGuardar[0].Principal.ignicion=RegHco[0].Principal.ignicion;
RegGuardar[0].Principal.movimiento=RegHco[0].Principal.movimiento;
RegGuardar[0].Principal.distancia=RegHco[0].Principal.distancia;
RegGuardar[0].Incremental[0].incTiempo=RegHco[0].Incremental[0].incTiempo;
RegGuardar[0].Incremental[0].seD=RegHco[0].Incremental[0].seD;
RegGuardar[0].Incremental[0].numSat=RegHco[0].Incremental[0].numSat;
RegGuardar[0].Incremental[0].edadP=RegHco[0].Incremental[0].edadP;
RegGuardar[0].Incremental[0].incLatitud=RegHco[0].Incremental[0].incLatitud;
RegGuardar[0].Incremental[0].incLongitud=RegHco[0].Incremental[0].incLongitud;
RegGuardar[0].Incremental[0].velocidad=RegHco[0].Incremental[0].velocidad;
RegGuardar[0].Incremental[0].ignicion=RegHco[0].Incremental[0].ignicion;
RegGuardar[0].Incremental[0].movimiento=RegHco[0].Incremental[0].movimiento;
RegGuardar[0].Incremental[0].incDistancia=RegHco[0].Incremental[0].incDistancia;*/
copiarEstructura(RegHco[0],&RegGuardar[0]);
fichero=fopen("pruebaBits.dat", "w+b");
tamano=fwrite(RegGuardar,sizeof(*RegGuardar),1,fichero),
fclose(fichero);
printf("El tamaño es: %d\n",tamano);
delete(RegGuardar);
fichero=fopen("pruebabits.dat","rb");
tamano=fread(&Registro,sizeof(Registro),1,fichero);
fclose(fichero);
printf("El tamaño leído es: %d\n",tamano);
printf("Total: %d\n",Registro.Principal.total);
printf("Año: %d\n",Registro.Principal.ano);
printf("Tiempo: %d\n",Registro.Principal.tiempo);
printf("Distancia: %d\n",Registro.Principal.distancia);
printf("Latitud y Longitud: %d,
%d\n",Registro.Principal.latitud,Registro.Principal.longitud);
printf("incTiempo: %d\n",Registro.Incremental[0].incTiempo);
printf("incDistancia: %d\n",Registro.Incremental[0].incDistancia);
printf("incLatitud e incLongitud: %d,
%d\n",Registro.Incremental[0].incLatitud,Registro.Incremental[0].incLongitud);
return 0;
}
0000010: 886c faff 7c64 0080 e803 d0cd 18fc cfcd .l..|d..........
0000020: e803 f8ce e803 cdcd 0000 00cd 0000 cccd ................
0000030: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................
0000040: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................
0000050: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................
0000060: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................
0000070: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................
0000080: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................
0000090: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................
00000a0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................
00000b0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................
00000c0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................
00000d0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................
00000e0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................
00000f0: 0000 00cc 0000 cdcd 0000 00cd 0000 cccd ................
0000100: 0000 00cc 0000 cdcd 0d0a ..........
00000010100110101100110111001101000000110000000000000000001100001100110111001101110011011100110101000111100111010100000000000000
10001000011011001111101011111111011111000110010000000000100000001110100000000011110100001100110100011000111111001100111111001101
11101000000000111111100011001110111010000000001111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101110011011100110111001101
11001101110011011100110111001101110011011100110111001101110011010000110100001010
Sin embargo, para los valores que le doy, se supone que la primera
00000010001101000000000000000000011000000000011100000000010000001001110101000111100000000000010110010011011110001111001000000000000000001100100
Cosa que no coincide. De ahí, mis dudas. Espero que podáis ayudarme.
Un saludo y muchas gracias.
lestat_l
2006-01-24 10:25:32 UTC
Permalink
Lo curioso es que he buscado el patrón del "100" (1100100 en binario)
para intentar averiguar cómo estaba organizado el archivo, y no
aparece por ninguna parte. Ese es el valor que tiene el registro en la
parte de distancia. ¿Cómo puede estar organizado el archivo para que
no aparezca dicho valor? ¿Hay alguna forma de forzar que en el archivo
aparezca exactamente lo que quiero?

Necesito que se guarde exactamente como le indico en los campos de bit,
porque necesito ese formato. ¿Cómo podría hacerlo? Teniendo en
cuenta que el sistema final tendrá grandes restricciones de memoria y
procesado, ya que se tratará de un sistema embebido.

Muchas gracias, y un saludo.
J.A. Gutierrez
2006-01-24 10:52:00 UTC
Permalink
In es.comp.lenguajes.c lestat_l <***@zensearch.com> wrote:
: Lo curioso es que he buscado el patrón del "100" (1100100 en binario)
: para intentar averiguar cómo estaba organizado el archivo, y no
: aparece por ninguna parte. Ese es el valor que tiene el registro en la
: parte de distancia. ¿Cómo puede estar organizado el archivo para que

deberias enviar un codigo de ejemplo mucho mas simple
(un caso minimo que reproduzca el comportamiento que no
funciona como esperas).

: no aparezca dicho valor? ¿Hay alguna forma de forzar que en el archivo
: aparezca exactamente lo que quiero?
: Necesito que se guarde exactamente como le indico en los campos de bit,
: porque necesito ese formato. ¿Cómo podría hacerlo? Teniendo en

Si quieres almacenar los datos en memoria, en estructuras
de alto nivel, y luego volcar eso, no te queda mas remedio
que estudiarte como te almacena los datos el compilador.
Es muy probable que meta espacios "de relleno" por cuestiones
de alineacion.

Para evitarte problemas, tienes que intentar que tu definicion
de campos de bits no haga que existan elementos que quedarian
"a caballo" entre dos palabras.

Suponiendo que como sea te has quitado los problemas del "relleno",
luego, para escribir los datos a disco te puede interesar definir
la estructura como union (con un char[]) y escribir caracter a
caracter

http://www.cs.cf.ac.uk/Dave/C/node13.html#SECTION001320000000000000000
--
PGP and other useless info at \
http://webdiis.unizar.es/~spd/ \
finger://daphne.cps.unizar.es/spd \ Timeo Danaos et dona ferentes
ftp://ivo.cps.unizar.es/pub/ \ (Virgilio)
Carlos Martinez Garcia
2006-01-24 12:14:48 UTC
Permalink
Hola lestat_l

Yo si que encuentro el patrón que mencionas en tu fichero (lo que no me
he puesto a comprobar es que coincide con el campo que dices porque no
lo he comprobado)

Directamente no se me ocurre ninguna forma.
En dos pasos por el contrario, se me ocurre que podrías crear un stream
en representación ascii del binario con bitstream (nunca lo he probado
con campos de bit, sólo es una sugerencia).
Una vez hecho esto, podrías fraccionarlo en bloques de 8 caracteres
(también es posible en otros múltiplos de 16 o 32), de forma que lo que
cojas sean bytes y ya a partir de eso convertirlo a bytes binarios que
serían los que grabases.

Remarco lo de que es una sugerencia para que lo mires ya que nunca lo he
probado, y antes de ponerte a hacerlo revisaría la documentación de
streams y bitstreams para asegurarme.

Un saludo
Post by lestat_l
Lo curioso es que he buscado el patrón del "100" (1100100 en binario)
para intentar averiguar cómo estaba organizado el archivo, y no
aparece por ninguna parte. Ese es el valor que tiene el registro en la
parte de distancia. ¿Cómo puede estar organizado el archivo para que
no aparezca dicho valor? ¿Hay alguna forma de forzar que en el archivo
aparezca exactamente lo que quiero?
Necesito que se guarde exactamente como le indico en los campos de bit,
porque necesito ese formato. ¿Cómo podría hacerlo? Teniendo en
cuenta que el sistema final tendrá grandes restricciones de memoria y
procesado, ya que se tratará de un sistema embebido.
Muchas gracias, y un saludo.
Antoine Leca
2006-01-24 16:20:20 UTC
Permalink
Post by lestat_l
Tengo un pequeño problema con campos de bit. El caso es que necesito
que en un archivo se guarden datos con un número específico de bits,
y para ello pensé utilizar los campos de bit,
En general, mala idea.
Post by lestat_l
que me parecieron una alternativa más lógica que hacer desplazamientos
y máscaras para conseguir poner los valores adecuados.
Los campos de bits (con las máquinas actuales) no generan ninguna ventaja, y
tienen muchísimos aspectos sin normativa, por lo cual es mejor pasarse de
ellos, y aún más cuando se trata de intercambio de datos.
Post by lestat_l
- ¿Cómo se almacenan estos campos de bit realmente?
Como le gusta al compilador. Si le gusta de derecho a izquierda pués eso. Si
no, pués el contrario. Si le gusta alineado en frontera de word o de dword,
pués eso. Si se preocupa de compatibilidad con las versiones anteriores,
pués ni siquiera será necesariamente lo más eficaz (y no importa, porque por
regla general no se usan). Etc.
Post by lestat_l
- ¿Por qué, si inicializo los campos a 0, no guarda ceros en el
archivo, en las posiciones donde no he escrito otra cosa?
No lo entiendo muy bién, pero en las posiciones donde tú no has escrito
ninguna cosa, por regla general puede haber cualquier cosa...
Post by lestat_l
typedef struct sPrincipal{
unsigned int total:8;
Empezará en 0 bit 0, ocupará 1 byte.
Post by lestat_l
unsigned int ano:7;
Empezará en 1 bit 0, ocupará 7 bits (0 hasta 6).
Post by lestat_l
unsigned int tiempo:20;
Problemas. Primero, en un compilador de 16 bits, eso no vale.
Puede estar en el mismo word que el precedente, pero no confies en eso
(porqué 8+7+20=35, superior a 32). Entonces puede empezar en 2 o en 4, bit
0. Hasta el 4 o el 6, bit 3.
Post by lestat_l
unsigned int seD:8;
Aquí puedes tenerlo como suelto (todo los bits) en byte 5 o 7, o colgado al
precedente en byte 4-5 o 6-7, bits de 4 hasta 3.

Et cetera.


Eso, sin olvidar que la númeración de cual es el bit 0 puede variar (¿él de
menor valor, o él de más valor? ¿del byte, o del word?)
En máquina Intel en general es coherente y es el primero (empeza por el de
menor valor), pero con otra arquitectura puede haber de todo.


Antoine

Loading...