6Fermer8
GoldenCrystalLe 10/05/2013 à 12:40
./4 > C'est du C# avec, il me semble, le compilateur JIT x86 (.NET 4.5). (Le souci c'est que le compilateur JIT sera différent selon la machine utilisée, voir même la version (future) de .NET, donc ce n'est pas un truc sur lequel je peux me reposer -_-)
À priori, le mode d'arrondi est "au plus proche", et le FPU est réglé sur la précision double (et non la précision étendue, même si autorisé par les specs).
Les spec C#/CLI autorisent gracieusement les opérations à être effectuées à une précision supérieure (ça alors !) donc, à priori, ce qui se produit pour "(int)(1666.42859f * 1.4f)" correspond à ça :
(int)(double)((double)1666.42859f * (double)1.4f)
2332

À priori, le résultat intermédiaire devrait donc être celui-ci : 1666.4285888671875 * 1.3999999761581421 = 2332.9999846833089d

Cela s'arrondit à un float qui vaut 2333.0f (le .0 affiché m'indique qu'il y a un petit truc en plus, mais flemme de regarder ce que c'est), et qui se convertit bien en entier 2333. Le souci c'est que le compilateur et/ou le runtime ne se sent pas obligé de convertir le résultat intermédiaire (même en insérant un cast explicite vers float), donc je retombe sur 2332…

Mon code original utilisait Math.Ceiling (prend un double, retourne un double), donc je tombais bon là dessus mais je me foirais dans d'autres cas, ce qui m'a amené à faire autrement… :/


Au final, j'ai fini par arrondir comme tu le suggères. Je sais de toutes façons que je dois forcément retomber sur un entier à la fin du calcul, là au moins ça élimine les ambiguïtés, et ça devrait fonctionner de manière similaire quel que soit le couple JIT/CPU…

En tout cas, merci.


(PS : c'est du code qui travaille avec une API basé sur des double et une autre basée sur des float (ben voyons…), et qui travaillent toutes deux avec des pixels réels (int) et des pixels logiques ("DIP", soit avec des float, soit avec des double), donc il y a forcément des conversions à faire de l'une à l'autre. Les erreurs de précision ne me dérangent pas le moins du monde (pour l'instant) tant que l'on reste dans le domaine de la virgule flottante, mais par contre, lorsque je convertis en entier, il faut que le résultat soit bon au pixel près, sinon aucun intérêt. grin)

./5 & ./6 > grin