Non, ce n'est pas un autre "Pourquoi est - (1/3.0)x3 != 1.0" question.
J'ai lu à propos de floating points beaucoup ces derniers temps; plus précisément, comment le même calcul peut donner des résultats différents sur des architectures différentes ou des paramètres d'optimisation.
C'est un problème pour les jeux vidéo qui stockent des replays, ou peer-to-peer en réseau (par opposition au serveur-client), qui s'appuient sur tous les clients de générer exactement les mêmes résultats à chaque fois qu'ils exécuter le programme - un petit écart dans un calcul flottant peut conduire à une drastique de jeu différents-de l'état sur des ordinateurs différents (ou même sur la même machine!)
Ce qui se passe, même parmi les processeurs qui "suivent" la norme IEEE-754, principalement parce que certains processeurs (à savoir x86) l'utilisation de double précision étendue. Qui est, ils utilisent 80 bits des registres de faire tous les calculs, puis tronquer à 64 ou 32 bits, conduisant à différentes arrondissant les résultats que les machines qui utilisent 64 ou 32 bits pour les calculs.
J'ai vu plusieurs solutions à ce problème en ligne, mais tous pour C++, C#:
- Désactiver le double extended-mode précision (de sorte que tous
double
le calcul de la norme IEEE-754 64-bits) à l'aide d'_controlfp_s
(Windows),_FPU_SETCW
(Linux?), oufpsetprec
(BSD). - Toujours exécuter le même compilateur avec les mêmes paramètres d'optimisation, et d'exiger que tous les utilisateurs ont la même architecture de PROCESSEUR (pas de cross-play). Parce que mon "compilateur" est en fait le JIT, ce qui peut optimiser différemment à chaque fois, le programme est exécuté, je ne pense pas que ce soit possible.
- L'utilisation de la virgule fixe de l'arithmétique, et d'éviter
float
etdouble
tout à fait.decimal
serait de travailler à cette fin, mais serait beaucoup plus lent, et aucun de l'System.Math
bibliothèque de fonctions de soutien.
Donc, est-ce encore un problème en C#? Que faire si je ne l'intention de soutenir l'Windows (pas Mono)?
Si elle l'est, est-il un moyen de forcer le programme à exécuter à la normale en double précision?
Si non, existe-il des bibliothèques qui permettrait de garder des calculs en virgule flottante-elle cohérente?