Convertir un uint16_t en double

Bonjour à tous,

Ma question est relativement simple et ne trouvant rien de satisfaisant sur internet je me tourne vers vous.

Pour un projet j'utilise deux bibliothèques une qui manipule des uint16_t et une autre des double. Avec la première bibliothèque j'obtiens un élément (une distance pour être précis) en uint16_t ensuite je souhaite traiter cette distance (avec filtre de kalman étendu) dont la bibliothèque utilise des double.
Ma question est la suivante est ce que la manipulation suivante est valide ?

uint16_t dist1 = tfmini.getDistance();        //premiere bibliotheque qui utilise des uint16_t
uint16_t dist2 = tfmini.getDistance();
double z[2]={(double) dist1, (double) dist2};    //manipulation dont je ne suis pas certain
ekf.step(z);                                             // deuxieme bibliotheque qui utilise des double

J'ai lu sur internet que les double étaient codés sur 64bits alors que les uint16_t sur 16bits. Je passe alors d'un nombre entier codé sur 16 bits à un nombre flottant codé sur 64 bits (j'avoue ne pas être extrêmement familier avec ces notions de tailles de données). Dois-je effectuer une manipulation supplémentaire ? Est-ce que je peux "forcer" un nombre codé sur 16 bits à passer sur 64 bits sans problèmes ?

Mes questions semblent quelques peu élémentaires mais je préfère demander (après tout comme disait Einstein "Il n'y a pas de question idiote, seulement une réponse idiote" )

Merci ;D

Bonjour,

Le manière dont tu as fait la conversion est tout à fait correcte. Vérifies quand même que les unités retournées par getDistance() et requises par step() soient les mêmes.
Il y a aussi une conversion implicite si nécessaire.

La conversion ne dépend pas de la taille des uint16_t ou double.
La taille des double dépend de la plateforme et n'est pas forcément de 64 bits (bien que ce soit souvent le cas). Avec un processeur avr un double fait 32 bits.

D'accord super merci !

les promotions vers les types plus étendus sont automatiquement réalisées par le compilateur donc même pas besoin de faire le changement de type.

double z[2];
z[0] = tfmini.getDistance();  // le uint16_t sera automatiquement promu en double
z[1] = tfmini.getDistance();
ekf.step(z);

Et à l'envers, ça donnera quoi ? Si le contenu 32 bits ne tient pas dans les 16 bits, on perd l'information ?

lesept:
Et à l'envers, ça donnera quoi ? Si le contenu 32 bits ne tient pas dans les 16 bits, on perd l'information ?

oui il tronque et prendra les 16 bits de poids faible.

volatile uint32_t ui32 = 0x44332211;
volatile uint16_t ui16; // volatile pour éviter des optimisations du compilateur

void setup() {
  Serial.begin(115200);
  ui16 = ui32;
  Serial.print(F("ui32 = 0x")); Serial.println(ui32, HEX);
  Serial.print(F("ui16 = 0x")); Serial.println(ui16, HEX);
}

void loop() {}

ça devrait afficher dans le moniteur Série

[color=purple]
ui32 = 0x4433[color=red]2211[/color]
ui16 = 0x[color=red]2211[/color]
[/color]

D'un double vers un uint16_t Attention aux optimisations du compilateur si les constantes ne sont pas volatiles, il fera des maths avant de compiler et vous pourriez avoir un résultat différent

volatile uint16_t ui16;

double d32_0 = 65534.39421;
double d32_1 = 65535.39421;
double d32_2 = 65536.39421;
double d32_3 = 130000.39421;

volatile double vd32_0 = 65534.39421;
volatile double vd32_1 = 65535.39421;
volatile double vd32_2 = 65536.39421;
volatile double vd32_3 = 130000.39421;

void setup() {
  Serial.begin(115200);
  
  Serial.println(F("PAS VOLATILE"));
  ui16 = d32_0; Serial.print(F("ui16_0 = ")); Serial.println(ui16);
  ui16 = d32_1; Serial.print(F("ui16_1 = ")); Serial.println(ui16);
  ui16 = d32_2; Serial.print(F("ui16_2 = ")); Serial.println(ui16);
  ui16 = d32_3; Serial.print(F("ui16_3 = ")); Serial.println(ui16);

  Serial.println(F("\nVOLATILE"));
  ui16 = vd32_0; Serial.print(F("ui16_0 = ")); Serial.println(ui16);
  ui16 = vd32_1; Serial.print(F("ui16_1 = ")); Serial.println(ui16);
  ui16 = vd32_2; Serial.print(F("ui16_2 = ")); Serial.println(ui16);
  ui16 = vd32_3; Serial.print(F("ui16_3 = ")); Serial.println(ui16);
}

void loop() {}

va donner

[color=purple]
PAS VOLATILE
ui16_0 = 65534
ui16_1 = 65535
ui16_2 = 65535
ui16_3 = 65535

VOLATILE
ui16_0 = 65534
ui16_1 = 65535
[b][color=red]ui16_2 = 0
ui16_3 = 64464[/color][/b]
[/color]