entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

5votos

Cómo dividir un Int en dos Bytes en C ?

Hola,

estoy trabajando con un software embebido en hardware mínimo que solo soporta ANSI C y tiene versiones mínimas de las bibliotecas standard IO.

Tengo una variable Int, de dos bytes de tamaño, pero necesito dividirla en 2 bytes por separado para poder transmitirlo, y luego poder, leyendo los dos bytes, volver a armar el Int original.

A mi se me ocurre alguna división binaria de cada byte como esta:

int valor = 522;  // 0000 0010 0000 1010 (entero de 2 bytes)
byte superior = byteSuperior(valor);  // 0000 0010
byte inferior = byteInferioror(valor);  // 0000 1010
...
int valorRestaurado = bytesToInteger(superior, inferior); // 522

pero no acierto a una forma simple de dividir el entero por su peso y me da la sensación de que debería ser trivial (como por ejemplo con corrimiento de bits) y no lo descubro.

En realidad, cualquier solución que divida al entero en 2 bytes y lo vuelva a armar me sirve.

Desde ya, muchas gracias!

3 Respuestas

3votos

No estoy seguro de que sea posible, ¿pero no podrías hacerlo con operadores lógicos? es decir, algo como:

int variable = 20;
char parteBaja = (char) 0x00FF & variable;
char parteAlta = (char) 0x00FF & (variable >> 8); //Desplazamos los 8 bits más significativos a una posición menos significativa introduciendo 0s por la izquierda

No estoy seguro de que esta respuesta sea válida, pero por proponer un idea ahí está.

Saludos.

0voto

Leonardo-Tadei comentado

Gracias!

esa es la parte del problema que más claro tengo. Pero, como los vuelvo a armar para que formen el Int original otra vez?

1voto

humberto_garcia_caba comentado

Pues suponiendo que partimos del código que puse sería algo así:

int variableReconstruida = (int) ((parteAlta << 8) | parteBaja);

Es decir, haciendo un OR de la parte alta desplazada 8 bits con la parte baja obtendríamos el valor inicial. De nuevo, vuelvo a comentar que no estoy seguro de que este código sea correcto, pero por proponer una primera idea quizás podría valer.

Saludos.

0voto

Leonardo-Tadei comentado

Hola Humberto!

gracias a tu primer respuesta hoy a la tarde pude resolverlo, y tal cual como apuntás ahora con un corrimiento de bits para el otro lado y un OR vuelvo a armar el entero.

Dejo el código completo por si sirve a alguien más. Estoy usando shrot int en vez de int a secas, porque en la PC los int son de 4 bytes y en mi plataforma destino son de 2. Uso unsigned para que sea más fácil debbuguear.

El código compila con GCC (y debería hacerlo con casi cualqueir otro compilador C). Si no veo mal, tiene una dependencia de que la arquitectura sea big endian o little endian, pero se solucionaría invirtiendo la línea que reconstruye el entero:

#include <stdio.h>

    void main(){
    // unsigned short int ocupa 2 Bytes en una PC cuya palabra sea de 32bits
    unsigned short int valor;
    unsigned short int rearmado;
    unsigned char data0 = 0;
    unsigned char data1 = 0;

    printf("Un entero ocupa %d bytes\n", sizeof(valor));

    printf("Ingrese un número: \n");
    scanf("%d",&valor);
    // Descompone el int en 2 bytes
    data0 = (char) 0x00FF & valor;
    data1 = (char) 0x00FF & (valor >> 8);
   // Muestra lo que hizo
    printf("Integer: %d \n", valor);
    printf("Hexa: %X \n", valor);
    printf("Byte 0: %d - %X \n", data0, data0);
    printf("Byte 1: %d - %X \n", data1, data1);
    // rearma el int a partir de los 2 bytes
    rearmado = (unsigned short int) (data1 << 8 | data0);
    // muestra el int reconstruido
    printf("Rearmado Integer: %d \n", rearmado);
    printf("Rearmado Hexa: %X \n", rearmado);

    return;
}

Saludos y gracias!

-1voto

Hola que tal @Leonardo-Tadei , pensando en tu misma solución ya no pude pensar en otra mas, jajaja parece muy obvia, No se mucho de este tema, encontré esto.. espero te ayude..

http://stackoverflow.com/questions/1735840/how-do-i-split-an-integer-into-2-byte-binary

0voto

Leonardo-Tadei comentado

Gracias!

esa es la parte del problema que más claro tengo, igual el ejemplo en Java no es tan transportable a C porque por ejemplo no tiene un tipo de dato byte. Pero, como los vuelvo a armar para que formen el Int original otra vez?

0voto

gasparfm Puntos140

Hola hace poco posteé en mi blog varias formas de hacer lo que tú dices: http://totaki.com/poesiabinaria/2015/12/como-extraer-la-parte-alta-y-la-parte-baja-de-un-numero-con-varios-ejemplos-en-c/
Porque si me aprietas, puedes hasta hacer dos punteros que apunten cada uno a una parte distinta del int, con las consecuentes ventajas e inconvenientes.

Un saludo

0voto

Leonardo-Tadei comentado

Gracias @gasparfm,

la solución está más o menos dentro de la respuesta anterior.

Interesante lo de tratarlo como un puntero. El artículo estaría más claro si apareciera el código de la función char_a_binario()

Saludos cordiales!

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta