La multiplication ne marche plus!

Bonjour
Je veux faire une multiplication en 64 bits avec un ESP32 mais impossible d'avoir le bon résultat : où est-ce que je me plante ????

Voici le code :

void setup() {
  Serial.begin(115200);
  uint32_t A = 3590324;
  uint32_t B = 1325400;
  uint64_t C = A*B;
  Serial.println(A);
  Serial.println(B);
  Serial.println(C);
  Serial.printf("%llu\n",C);
}

void loop() {}

Je m'attends à obtenir le résultat de 4 758 615 429 600, mais j'obtiens ça :

3590324
1325400
4086632928
4086632928

Keski se passe ?

Bonjour @lesept
Sur ESP32 vous êtes en 32 bits.
Bonne journée

Et pourtant sur un Arduino Uno on est en 8 bits et on utilise bien le type de variable int.

Le problème ne vient pas du fait que la multiplication de deux entier 32bits donne un entier sur 32bits?
As tu essayé de faire ça? :
uint64_t C = (uint64_t )A*(uint64_t )B;

C'est ça, merci !!!

Oui c'est vrai @terwal

@lesept
En fait lorsque vous multipliez deux uint32_t A et B, le résultat même si il est déclaré en uint64_t sera d'abord en uint32_t puis il sera converti en uint64_t. Enfin il sera affecté a la variable C d'où l'erreur dans le résultat ... En fait il vous suffit d'avoir une seule des deux variables en uint64_t :

uint64_t A = 3590324;
uint32_t B = 1325400;
uint64_t C = A * B;
void setup() {
  Serial.begin(115200);
  Serial.println(A);
  Serial.println(B);
  Serial.println(C);
  Serial.printf("%llu\n", C);
}

void loop() {}

Donne :

3590324
1325400
4758615429600

Autre exemple vous divisez deux int et vous voulez un résultat en float :

float C;
int A, B;
void setup() {
  Serial.begin(115200);
  A = 3;
  B = 2;
  C = A / B;
  Serial.println(A);
  Serial.println(B);
  Serial.println(C);
}

void loop() {}

donne :

3
2
1.00

alors que :

float C;
int A;
float B;
void setup() {
  Serial.begin(115200);
  A = 3;
  B = 2;
  C = A / B;
  Serial.println(A);
  Serial.println(B);
  Serial.println(C);
}

void loop() { }

donne :

3
2.00
1.50

Tous ces exemples constituent une conversion de type implicite mais comme le préconise @terwal, on pourra effectuer une conversion de type explicite en castant les variables...
Bonne soirée.
PS : Le CPU des ESP32 est architecturé en 32 bits. sur cette plateforme, les uint64_t sont codés sur 8 octets (comme les double) donc sur 64 bits mais ça n'a rien à voir avec le sujet.

ÉDITÉ UNE FOIS

Bonjour à tous,
Est-ce que je me trompe si en simplifiant je dis q'un CPU qui fonctionne en 32 bits est capable de traiter 4 octets de données en un seul cycle d'instruction (cycle d'horloge). En 64 bits il peut en traiter 8 ? Ses registres, les bus d'adresses et de données ont en principe cette taille (32 ou 64 bits) ?

Merci.

Lorsqu'on parle de CPU 32 bits on parle de la taille des registres et de l'ALU (Unité Arithmétique et Logique).
La taille du bus de données est généralement différente de la taille du bus d'adresse.
La taille du bus de données n'est pas toujours égale à la taille des registres de donnée. Le meilleur exemple étant le 80188 qui avait une ALU 16 bits et un bus de donnée 8 bits

Ca dépend de ce que tu appel traiter.
L'architecture 32bit et 64bit manipulent des données ou des adresses correspondant à leur intitulé.
C'est la taille d'un bus physique, donc effectivement on peut transférer un mot de la taille du bus en une seul fois et x fois pour un mot x fois plus grand.

Oups fdufnews a déjà très bien répondu.

Cela dépend totalement du processeur.
Certains processeurs sont capables d'effectuer certaines opérations en 1 cycles, d'autres non.
Pour obtenir ce renseignement il faut examiner le jeu d'instructions ASM.
Sur CORTEX M3, un MOVE prend 1 cycle
Sur ESP32, un MOVE prend 2 cycles

Merci @fdufnews, merci @hbachetti pour ces précisions intéressantes.

Et merci @terwal.

Bonjour @terwal,
Bonjour @lesept,

Il faut utiliser les transtypages du C++ moderne :

uint64_t C = static_cast<uint64_t> (A) * static_cast<uint64_t>(B);

ou

uint64_t C = static_cast<uint64_t> (A) * B;

Bonne journée à tous les deux.

@terwal,
je pense que :

  • Il n'y a pas de risque de débordement ;
  • il n'y a pas de risque de perte de précision ;
  • la conversion est sûre car un uint32_t est toujours convertible en un uint64_t.

Bonne journée.