Question

Mon application génère différentes valeurs en virgule flottante lorsque je la compile en mode publication et en mode débogage. La seule raison pour laquelle j’ai découvert cela est que j’ai sauvegardé un journal de trace binaire et que celui de la version finale est légèrement différent de la version de débogage, il semble que les deux derniers bits des valeurs 32 bits flottantes diffèrent environ de 1/2. des cas.

Considérez-vous cette "différence"? être un bug ou ce type de différence serait attendu. S'agirait-il d'un bogue du compilateur ou d'un bogue de bibliothèque interne?

Par exemple:

LEFTPOS and SPACING are defined floating point values.
float def_x;
int xpos;

def_x = LEFTPOS + (xpos * (SPACING / 2));

Le problème concerne le compilateur X360.

Était-ce utile?

La solution

Le mode de libération peut avoir un jeu de stratégie de PF différent. Il existe différents modes arithmétiques en virgule flottante en fonction du niveau d'optimisation souhaité. MSVC, par exemple, a des modes stricts, rapides et précis.

Autres conseils

Je sais que sur PC, les registres à virgule flottante ont une largeur de 80 bits. Ainsi, si un calcul est effectué entièrement dans la FPU, vous bénéficiez de 80 bits de précision. Par ailleurs, si un résultat intermédiaire est déplacé vers un registre normal et inversement, il est tronqué à 32 bits, ce qui donne des résultats différents.

Considérons maintenant qu'une version de version comportera des optimisations qui conserveront les résultats intermédiaires dans les registres FPU, alors qu'une version de débogage copiera probablement naïvement les résultats intermédiaires en arrière et en avant entre la mémoire et les registres - et vous avez votre différence de comportement.

Je ne sais pas si cela se produit ou non sur X360.

J'ai aidé un collègue à trouver un commutateur de compilateur différent du build par rapport à la version de débogage causant ses différences.

Consultez / fp (Spécifier le point flottant Comportement) .

Ce n'est pas un bug. Toute ascension en virgule flottante a une certaine imprécision. En mode Release, l’optimisation modifiera l’ordre des opérations et vous obtiendrez un résultat légèrement différent. La différence devrait être petite, cependant. Si c'est grand, vous pourriez avoir d'autres problèmes.

En plus des différents modes à virgule flottante signalés par d’autres, les optimisations SSE ou des vecteurs similaires peuvent être activées pour la publication. La conversion de l'arithmétique en virgule flottante de registres standard en registres vectoriels peut avoir une incidence sur les bits les plus faibles de vos résultats, car les registres de vecteurs seront généralement plus étroits (moins de bits) que les registres à virgule flottante standard.

Pas un bug. Ce type de différence est à prévoir.

Par exemple, certaines plates-formes ont des registres flottants qui utilisent plus de bits que ce qui est stocké en mémoire. Conserver une valeur dans le registre peut donner un résultat légèrement différent par rapport au stockage en mémoire et au rechargement à partir de la mémoire.

Cette différence peut très bien être causée par l’optimisation du compilateur, qui est généralement effectuée en mode de publication, mais pas en mode débogage. Par exemple, le compilateur peut réorganiser certaines opérations pour accélérer l’exécution, ce qui peut éventuellement entraîner une légère différence dans le résultat en virgule flottante.

Donc, je dirais très probablement que ce n’est pas un bug. Si cela vous inquiète vraiment, essayez d'activer l'optimisation en mode débogage.

Comme d’autres précités, la précision des registres à virgule flottante est supérieure à celle des flottants, de sorte que la précision du résultat final dépend de l’affectation des registres.

Si vous avez besoin de résultats cohérents, vous pouvez rendre les variables volatiles, ce qui se traduira par des résultats plus lents, moins précis, mais cohérents.

Si vous définissez un commutateur de compilateur autorisant le compilateur à réorganiser les opérations en virgule flottante, par exemple. / fp: fast - alors évidemment ce n'est pas un bug.

Si vous n'avez défini aucun commutateur de ce type, il s'agit d'un bogue: les normes C et C ++ n'autorisent pas les compilateurs à réorganiser les opérations sans votre autorisation.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top