Categorías: Tutoriales

Guardar un entero en cuatro char sin signo en C

En ocasiones, por motivos del protocolo utilizado en una comunicación, por la forma de acceder a la capa física o por cualquier otra razón similar, no podemos manejar directamente enteros de 4 bytes en nuestro programa, sino que debemos manejar valores de 1 sólo byte. No debemos preocuparnos, al fin y al cabo, podemos enviar un vector de 4 elementos de un tipo de dato que tenga 1 byte, por ejemplo, un carácter sin signo.

Gracias a la operación de desplazamiento de bits y al producto binario, la operación es casi inmediata. Veamos, la idea es guardar un entero de 4 bytes en un vector de 4 elementos de un byte de la siguiente manera:

  • Vector[0]: bits del 24 al 31 (parte más significativa)
  • Vector[1]: bits del 16 al 23
  • Vector[2]: bits del 8 al 15
  • Vector[3]: bits del 0 al 7 (parte menos significativa)

Por lo tanto, para almacenar el entero en dicho vector nos limitaremos a hacer lo siguiente:

unsigned char v[4];
v[0] = (n >> 24) & 0xFF;
v[1] = (n >> 16) & 0xFF;
v[2] = (n >> 8 ) & 0xFF;
v[3] = n & 0xFF;

Como véis, además de desplazar, multiplico por todo unos (FF) para asegurarnos de que el entero resultante se queda sólo con el byte que nos importa.

Ahora tenemos en base 256 un número de 4 bytes guardado en 4 cifras. ¿Cómo hacer la operación inversa? Muy simple, si en base 10 hacemos: unidades + decenas x 10 + centenas  * 100… en nuestro caso tendríamos:

resultado = v[0] * 16777216 + v[1] * 65536 + v[2] * 256 + v[3];
F. Javier Carazo Gil

Cofundador de CODECTION, empresa especializada en WordPress, autor de un libro sobre WordPress (el primero en español) y multitud de artículos (en medios físicos y virtuales) sobre el tema. Participa en la comunidad WordPress de forma activa siendo parte del equipo organizador de la WordPress Meetup de Córdoba, dando charlas en diferentes WordCamp y siendo autor y coautor de multitud de plugins libres y premium para WordPress de gran éxito.

Ver comentarios

  • ¿Y qué te parece esto?
    unsigned char Vector[4];
    memcpy(Vector, &n, 4*sizeof(char));

    Como las 4 posiciones de Vector son contiguas, al copiar todo el contenido de n en la posición inicial todas quedan rellenas. La operación inversa es el memcpy en el sentido contrario, claro. ¿Algún fallo?

  • Multiplicando por 0XFF no te extenderá el signo de la constante (0xFFFFFFFF); que yo recuerde, ese es el comportamiento habitual. ¿No debería ser 0X00FF para evitarlo?

    Saludos.

  • En el ejemplo que se muestra con operadores a nivel de bit se guarda la información siguiendo el formato de Big endian (que es el empleado para formato de red), así que el memcpy realiza la misma operación.
    No es necesario poner 4*(sizeof(char)) como tercer argumento en memcpy, pues el valor que coloquemos ahí se interpreta como N. de bytes.
    Y por último cuando aplican la máscara (yo prefiero llamarlo así ;)) 0xFF no se necesita colocar 0's adicionales a la izquierda, ya que la operación se realiza desde el Bit menos significativo al mayor, dando como mencionas el primer byte que es el utilizado.
    Saludos y ojalá publiquen más artículos como este.

  • @carazo: sea little endian o big endian, si la conversión de una forma a otra se hace con memcpy's inversos, dará igual. La diferencia sería que el MSB estaría en Vector[0] o Vector[3], creo yo

  • @Eduardo: Muchísimas gracias por tu aportación, mi duda ahora es si cambia el endian entre las máquinas que envíe y la que recibe los datos, al reconstruirlos con el memcpy creo que habría problemas. Con mi método creo que no habría problemas.

    @Surgat: Si cambia el MSB, el número se transmitirá al "revés" y será incorrecto al recomponerse.

    No tengo posibilidad de probarlo entre distintas arquitecturas para ver el resultado, si alguien puede aportarnos más claridad con pruebas reales, le estaría muy agradecido.

  • Excelente explicacion!! ahora a ver si funciona . . . sobre la HCR825 de ASK.

    Saludos!!

  • @JulianPrestas: Debería funcionar, son instrucciones muy cercanas al ensamblador.

Entradas recientes

DeepSeek

2 días hace

Contacto

2 semanas hace

Smart-tv mute

2 semanas hace

STEAM OS

3 semanas hace

2025

1 mes hace

El podcast de Linux Hispano – #072 – El hardware libre debe consolidarse como el software libre

https://www.youtube.com/embed/z-xGk9c_eOw Guionista y locutor: Manuel Ignacio López Quintero.Fecha de publicación: 31 de diciembre de 2024.

1 mes hace