Go Down

Topic: Convertir un uint16_t en double (Read 195 times) previous topic - next topic

michmichl

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 ?
Code: [Select]

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

kamill

#1
Mar 27, 2020, 10:38 am Last Edit: Mar 27, 2020, 10:44 am by kamill
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.

michmichl


J-M-L

#3
Mar 27, 2020, 02:53 pm Last Edit: Mar 27, 2020, 02:53 pm by J-M-L
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.

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


Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

lesept

Et à l'envers, ça donnera quoi ? Si le contenu 32 bits ne tient pas dans les 16 bits, on perd l'information ?
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

J-M-L

#5
Mar 27, 2020, 04:04 pm Last Edit: Mar 27, 2020, 04:17 pm by J-M-L
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.
Code: [Select]
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
ui32 = 0x44332211
ui16 = 0x2211


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
Code: [Select]
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
PAS VOLATILE
ui16_0 = 65534
ui16_1 = 65535
ui16_2 = 65535
ui16_3 = 65535

VOLATILE
ui16_0 = 65534
ui16_1 = 65535
ui16_2 = 0
ui16_3 = 64464


Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

Go Up