Transferir int32_t a int16_t

Buenas tardes noches comunidad de desarrolladores ! ... estoy desarrollando una api y me he topado con la siguiente situación :

Hay una función que retorna un entero de 32 bits con signo, ahora asigno ese valor a un entero de 16 bits por que debo de enviar datos por puerto serial y el otro dispositivo recibe por cada registro datos de 2 bytes osea 16 bits ... ahora en mi código estoy asignando el valor de 32 bits a la variable de 16 bits y al momento de imprimir por el puerto serial veo que se imprimen 32 bits pero el tamaño es de 2 bytes ... mi código es :

int32_t entero_doble = -43;
int16_t entero = entero_doble;

Serial.println("Los datos son : ");
Serial.print(entero_doble, BIN);  // en puerto serial veo 1111 1111 1111 1111 1111 1111 1101 0101
Serial.print("El tamaño de entero  es:");
Serial.println(sizeof(entero));     // en el puerto serial veo 2 que seria lo correcto 2 bytes = 16 bits !

Quizás estoy malinterpretando pero me gustaría conocer las opiniones de mas expertos !

Nota : Los 16 bits son suficientes para representar cualquier valor en el rango negativo y positivo pero de alguna manera dicha función no se por que carajos la desarrollaron de modo que retorne 32 bits ... de antemano mil gracias por su ayuda !

Esta variable es de 32 bits, que son los que imprime esta instrucción. Tal vez si imprimes

Serial.print(entero, BIN);

Si imprimes un valor positivo te va a truncar los 0 innecesarios para la representación, por ej. para 43 solo va a imprimir 101011. Se asume que sabes que delante son todos ceros.

Como un valor negativo tiene el bit más significativo en 1 no hay posibilidad de truncarlo y se muestran los 32 bits.

En caso de un int negativo va a ocurrir lo mismo salvo que solo se mostrarán 16 dígitos porque el int tiene 16 bits.

Ok me he equivocado usando la otra variable también veo los mismos 32 bits en el puerto serial :

Serial.println("Los datos son : ");
Serial.print(entero, BIN);

Al parecer al momento de imprimir sea la variable de 16 o 32 bits si el valor es positivo tienes razón solo imprime el ultimo dato mas significativo si es 1, para el caso de los negativos para los dos variables siempre imprime 32 bits, lo que no se si es la forma en que lo hago es la correcta

int32_t entero_doble  = -43;
int16_t entero = entero_doble ; 

De alguna manera desconozco si esta asignación para la variable de 16 bits tomara los 16 bits menos significativos de la variable de 32 bits sean valores positivos o negativos ...

Trunca literalmente el número, así que el signo se pierde.
Prueba esto

void setup() {
  Serial.begin(115200);
  int32_t largo = -32769;
  int16_t corto = (int)largo;

  Serial.println(largo);
  Serial.println(largo, BIN);

  Serial.println(corto);
  Serial.println(corto, BIN);
}

void loop() {
}

El -32769 tiene un solo bit en 0, el bit 15.
Al truncarlo a 16 bits, se pierden los 2 bytes mas significativos, se conserva el bit 15 en 0, y el int contiene 32767 positivo.

Efectivamente el signo es algo importante a tener en cuenta, mi desconocimiento me hizo reformular nuevamente mi inquietud ! al final encontré una solución convencional usando 2 bytes para formar un entero así el primer byte lo asigne al LSB del entero de 32 bits y el segundo byte lo asigne al MSB del entero de 32 bits ! Gracias por sus respuestas ... todo me ayudo a encontrar la solución mi código final es :


int32_t entero_doble = -64;
byte uno  = (byte) entero_doble ;
byte dos  = (byte) (entero_doble >> 8);

Creo que no es necesario que hagas eso, todo depende del rango de valores que vayas a usar.

Si el valor del entero largo está dentro del rango que puede contener un entero (-32768 a +32767) no vas a tener problemas con el signo.

Probá cambiando

int32_t largo = -32769;

por

int32_t largo = -32768;

(o -64 como en tu ejemplo) en el código de #6.
Así sí se conserva el signo.

Como te digo, depende del rango de los datos que vas a manejar.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.