J'ai lu beaucoup de choses sur virgule flottante déterminisme dans .NET, c'est à dire veiller à ce que le même code avec les mêmes entrées donnera les mêmes résultats sur différentes machines. Depuis .NET manque d'options comme Java fpstrict et MSVC de la fp:strict, le consensus semble être que il n'y a aucun moyen de contourner ce problème en utilisant uniquement du code managé. Le C# de jeu de l'IA de la guerre est réglé sur l'utilisation de la virgule Fixe les maths à la place, mais c'est une lourde solution.
Le principal problème semble être que le CLR permet de résultats intermédiaires à vivre dans les registres FPU qui ont une précision plus élevée que le type natif de précision, conduisant à impredictably plus grande précision des résultats. Un article MSDN par CLR ingénieur David Notario explique ce qui suit:
Notez qu'avec la spécialisation actuelle, c'est toujours un choix de la langue pour donner ‘la prévisibilité'. La langue peut insérer conv.r4 ou conv.r8 instructions après chaque FP pour obtenir un ‘prévisible' comportement. Évidemment, c'est très cher, et dans des langues différentes divers compromis. C#, par exemple, ne fait rien, si vous voulez rétrécissement, vous aurez à insérer (float) et (double) jette à la main.
Cela donne à penser que l'on peut atteindre à virgule flottante déterminisme simplement en insérant des conversions explicites pour chaque expression et la sous-expression qui s'évalue à flotteur. On pourrait écrire un wrapper type autour de flotteur pour automatiser cette tâche. Ce serait une solution simple et idéale!
D'autres observations suggèrent cependant qu'il n'est pas si simple. Eric Lippert a récemment déclaré (l'emphase est mienne):
dans certaines versions du moteur d'exécution, de casting pour flotter donne explicitement une autre résultat que de ne pas le faire. Lorsque vous effectuez un cast explicite de flotter, le compilateur C# donne une astuce pour l'exécution de dire "prendre cette chose de très haute précision en mode si vous arrive d'être en utilisant cette l'optimisation".
Quelle est cette "astuce" de l'exécution? Le C# spec prévoir qu'un cast explicite float provoque l'insertion d'une conv.r4 dans l'-t-IL? Le CLR spec stipulent qu'un conv.r4 instruction provoque une valeur à être réduit à sa taille d'origine? Seulement si ces deux sont vrai peut-on compter sur les conversions explicites de fournir à virgule flottante "prévisibilité", comme l'explique David Notario.
Enfin, même si on peut en effet contraindre tous les résultats intermédiaires du type de la taille d'origine, est-ce suffisant pour garantir la reproductibilité dans les machines, ou il y en a d'autres facteurs, comme la FPU/SSE paramètres d'exécution?