Duniter wotb : problème d'arrondi

@Moul @cgeek il semblerais que ce soit un problème d’arrondi, et la mauvaise nouvelle c’est que je ne peut pas simuler la façon dont C++ convertis de double vers uint32_t, donc je n’ai pas de solution :

Au moment des faits il y avait 1670 membres référents et Mart53 était suffisamment proche de 1335 d’entre eux soit environ 79,940119%

Or, 0.8 x 1670 = 1336, donc d’après ma calculatrice casio, Mart53 ne respecte pas la règle de distance.

Le problème ? Et bien pour une raison obscure, la plupart des compilateurs C++ vont déduire que 0.8 x 1670 = 1335 :confused:

J’ai trouvé ici quelqu’un qui a eu le même problème : http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka14326.html

Formule en Rust :

outdistanced = f64::from(success) < x_percent * f64::from(sentries)

f64 est l’équivalent du double en C++, ici on compare des doubles donc.

Formule en C++

result.isOutdistanced = result.nbSuccess < x_percent * result.nbSentries;

Sachant que nbSuccess et nbSentries sont des uint32_t, on compare donc des entiers.

Problème, si je transforme la formule en Rust pour comparer également des entiers, Mart53 ne passe toujours pas la règle de distance :

outdistanced: success < (x_percent * f64::from(sentries)).round() as u32,

Que je tente avec round(), ceil(), trunc() ou encore floor(), impossible d’obtenir le même résultat qu’en C++…

Le seul moyen de résoudre le problème c’est de faire un -1 :

outdistanced: success < ((x_percent * f64::from(sentries)).round() as u32 - 1)

Et cela résout le problème.

Je tiens toutefois a relativiser ce problème, d’après ma sync cautious en version oxydée ce problème avec Mart53 est le seul cas de toute l’histoire de la G1, il est très probable qu’on est jamais un tel cas de nouveau avant très longtemps, d’ici là tout le monde aura la version oxydée donc il n’y aura plus de delta dans la façon de faire les arrondis.

4 Likes