J'ai une petite classe de vecteurs 3D en C# 3.0 basée sur la structure qui utilise le double comme unité de base.La précision en virgule flottante peut-elle être dépendante du fil?
Un exemple: y-valeur un vecteur est
-20.0 straight
je soustrais un vecteur avec une valeur de y
10.094999999999965
La valeur pour y j'attendre est
-30.094999999999963 (1)
A la place, j'obtiens
-30.094999313354492 (2)
Lorsque je fais tout le calcul dans un seul thread, j'obtiens (1). Le débogueur et la fonction VS-watch reviennent également (1). Mais, quand je lance quelques itérations dans un thread et que j'appelle la fonction d'un thread différent, le résultat est (2). Maintenant, le débogueur renvoie aussi (2)!
Nous devons garder à l'esprit le .NET JIT pourrait écrire les valeurs en mémoire (site Web Jon Skeet) qui réduit la précision de 80 bits (FPU) à 64 bits (double). Cependant, l'exactitude de (2) est loin en dessous de cela.
La classe vecteur ressemble fondamentalement à ce
public struct Vector3d
{
private readonly double _x, _y, _z;
...
public static Vector3d operator -(Vector3d v1, Vector3d v2)
{
return new Vector3d(v1._x - v2._x, v1._y - v2._y, v1._z - v2._z);
}
}
Le calcul est aussi facile que ce
Vector3d pos41 = pos4 - pos1;
C'est vrai, j'utilise une bibliothèque qui crée un périphérique Direct3D. Merci! Existe-t-il un moyen de définir vous-même la précision du CLR, je veux dire en dehors de Direct3D? – msteiger
@ isométrique-dieu: Je soupçonne qu'il existe, mais je ne le sais pas. Je ne pense pas que ce soit une chose CLR - je suppose que c'est une propriété générale de "précision pour ce thread" pour tout le code, géré et non géré. –
Il n'y en a pas. Le CLR fait des hypothèses difficiles sur le mot de configuration FPU. Il existe un moyen de le réinitialiser, lancer et attraper une exception. Ensuite, maintenant, il est dans le mauvais état pour le code DirectX. –