2009-08-11 5 views
3

En raison de la difficulté pour la machine pour représenter des valeurs à virgule flottante exactement, nous utilisons la technique de Write Great Code: Understanding the machine pour effectuer des comparaisons à virgule flottante:Comment puis-je connaître dynamiquement le taux d'erreur en virgule flottante?

from the editor: please insert your code here. See HTML comment in the question source 

Actuellement, nous avons codé en dur la valeur « d'erreur ». Mais l'erreur est différente à travers différentes machines. Y at-il un bon moyen de comprendre, l'erreur pour une machine particulière, au lieu de coder en dur une tolérance?

Répondre

4

Voir my answer à What’s the smallest non-zero, positive floating-point number in Perl?.

Ce code trouve le plus petit nombre positif qui ne peut pas être distingué de zéro. Vous pouvez l'adapter à vos besoins.

+0

Est-il possible que nous puissions aller dans la boucle infini dans le cas de bord? Bien que cela ne semble pas à première vue. –

+0

Et cela semble être "approximatif", pas "exactement". –

+0

@Yan Cheng Cheok Je ne suis pas analyste numérique et je ne connais pas toutes les subtilités du calcul en virgule flottante dans toutes ses variétés, mais je ne le pense pas car les nombres flottants ne peuvent représenter qu'un nombre fini de valeurs. Si vous travaillez avec virgule flottante décimale (peu probable, mais possible), alors vous devez diviser par 10. –

1

La «précision de la machine» qui détermine la précision d'un double ou d'un flotteur est généralement étiquetée epsilon.

Si je dois calculer la précision d'un nombre à virgule flottante, je généralement quelque chose comme ça *.

float number = 1.0;  // precision of this number 
float epsilon = 1.0; 

while ((number + epsilon) != number) 
{ 
    epsilon /= 2.0f; 
} 

(* Ceci est du haut de ma tête Ne pas utiliser ce code sans vérification.)

Mais il existe des moyens de déterminer la précision exacte étant donné les propriétés de la machine.

Voici un article sur How to determine the machine epsilon avec des exemples de code.

Et un autre ici: Floating Point: Machine Precision avec la théorie et les équations pour calculer epsilon.

Profitez,

Robert C. Cartaino

3

64 bits IEEE 754 à virgule flottante, le plus petit nombre tel que 1.0 + e != 1.0 est e = 2.2204460492503131e-016. (DBL_EPSILON dans float.h en C, std::numeric_limits<double>().epsilon() en <limits> en C++). Je pense qu'il est peu probable que votre code s'exécute sur des systèmes où le format à virgule flottante natif n'est pas 64 bits IEEE 754.

Notez que la précision absolue change réellement en fonction de l'ampleur des nombres auxquels vous avez affaire. . Avec les dénormaux, vous travaillez sur des valeurs extrêmement petites, donc 1e-300 + 2e-300 fonctionnera, mais 1 + 1e-300 == 1. De même, 1e30 + 1 == 1e30.

3

Je détermine généralement la précision que je veux dans mon système, sans trop m'inquiéter de la précision dont je dispose. Cela fonctionne correctement dans la plupart des cas, j'ai rencontré. Certains des avantages que je peux penser de cette approche est que

  • Cela me permet de me concentrer sur le problème que j'essaie de résoudre plus rapidement.
  • Je ne dois pas passer du temps à essayer de comprendre l'epsilon!
  • également, et ceci est un point important: l'epsilon change en fonction de l'endroit où vous vous trouvez sur le système de numérotation. L'epsilon est différent près de 0, et différent près, disons 2^300.Donc, pour effectivement brancher un epsilon, vous devez également savoir quel numéro de gamme vous essayez de comprendre epsilon pour. Je suggère d'utiliser la réponse Sinan Unur's, mais faites le calcul près des valeurs limites de la plage de nombres que vous allez rencontrer, puis utilisez un epsilon légèrement plus grand que la valeur maximale.
  • vérifier le point trois, c'est juste une intuition!
+0

Oui, l'epsilon dépend du nombre considéré. Pour '1_000_000', il s'agit de' 1.1641532182693481e-010' et pour '1_000_000_000', il s'agit de' 1.1920928955078125e-007'. –

Questions connexes