Lorsque vous comparez des flotteurs, comment appelez-vous le seuil de différence?


10

Je compare des flotteurs en Java en ce moment et la formule la plus simple est:

Math.abs(a - b) < THRESHOLD

Lorsque vous nommez votre variable pour le seuil de différence, devez-vous la nommer delta ou epsilon ? Plus précisément, lequel des deux est le terme correct pour la plus petite valeur qu'un nombre à virgule flottante peut représenter?

Le terme langage de programmation est-il spécifique ou est-il universel d'un langage à l'autre?


1
Termes alternatifs: "précision", "résolution". Je les aime précisément;) car ils ne semblent pas trop techniques.
stakx

1
Hors-sujet: Le guide-virgule flottante recommande contre l' utilisation de ce type de comparaison quasi-égalité.
stakx

1
@stakx - les termes que vous proposez sont incorrects et ont des significations différentes de ce que le PO demande. La question est détaillée, oui, mais elle peut être répondue sur la base d'une référence externe et elle est pertinente pour la programmation lorsqu'il s'agit de valeurs à virgule flottante. C'est constructif et sur le sujet.

1
@ GlenH7: Je n'ai jamais dit que la question n'était pas bonne ou pas répondable. En fait, c'est moi qui l'ai voté. Et puisque vous prétendez que les termes (certes moins précis) que j'ai suggérés sont incorrects, je serais intéressé à savoir pourquoi .
stakx

@stakx - excuses pour avoir laissé entendre que vous aviez voté pour la fermeture. Je réagissais davantage aux quatre votes serrés sur la question en ce moment.

Réponses:


18

Epsilon en mathématiques et en génie

En mathématiques et en génie en général:

  • Delta est généralement utilisé pour désigner une différence, qui peut être de n'importe quelle échelle.
  • Epsilon est généralement utilisé pour désigner une quantité négligeable.

et epsilon semble plus approprié dans votre cas.


Epsilon en informatique

En informatique en particulier, le terme epsilon désigne également la machine espilon qui mesure la différence entre 1.0fet le plus petit flotteur strictement supérieur à 1.0f. Ce dernier nombre est 1.00000011920928955078125fpour les flottants en Java et peut être calculé avec:

float f = Float.intBitsToFloat(Float.floatToIntBits(1f) + 1);

La définition de epsilon machine est cohérente avec l'utilisation générale d'epsilon décrite ci-dessus.


Comparaison des flotteurs

Notez cependant qu'avant de comparer les flotteurs pour la "proximité", vous devez avoir une idée de leur échelle. Deux flotteurs très grands et supposés très différents peuvent être égaux:

9223372036854775808f == 9223372036854775808f + 1000000000f; //this is true!

Et inversement, il pourrait y avoir de nombreuses valeurs de flotteur possibles (et plusieurs ordres de grandeur) entre deux petits flotteurs qui diffèrent par la machine epsilon "uniquement". Dans l'exemple ci-dessous, il y a 10 000 000 de valeurs flottantes disponibles entre smallet f, mais leur différence est toujours bien en dessous de la machine epsilon:

float small = Float.MIN_VALUE; // small = 1.4E-45
float f = Float.intBitsToFloat(Float.floatToIntBits(small) + 100000000); // f = 2.3122343E-35
boolean b = (f - small < 0.00000011920928955078125f); //true!

L'article lié dans la réponse de GlenH7 étudie davantage la comparaison des flotteurs et propose plusieurs solutions pour surmonter ces problèmes.


2
-1: Dans les logiciels de calcul scientifique, Epsilon fait référence à Machine epsilon ou Relative epsilon (voir le même article). En règle générale, ce n'est pas la même quantité utilisée pour accepter l'égalité approximative, car les erreurs d'arrondi sont des multiples d'epsilons de machine ou d'epsilons relatifs, et généralement quelques ordres de grandeur plus grands que cela.
rwong

1
@rwong C'est une spécialisation du terme epsilon , et il y en a beaucoup d'autres. En ingénierie en général, epsilon fait référence à une petite quantité ou à une erreur et Machine epsilon est compatible avec cette idée.
assylias

@assylias, en utilisant un nom qui a une définition standard, dans un contexte où la définition standard a du sens, mais pour quelque chose qui ne correspond pas à la définition standard est un reçu pour les problèmes.
Programmeur

@AProgrammer Je ne suis pas d'accord avec le fait que la définition générale d'Epsilon ne s'applique pas à l'informatique.
assylias

1
@assylias: merci pour la clarification. J'ai supprimé mon -1.
rwong

16

En mathématiques, delta est utilisé pour représenter une certaine différence par rapport à une valeur, epsilon est utilisé pour représenter une valeur d'erreur arbitraire. Dans ce cas, epsilon serait le nom conventionnel.


8

Pour répondre directement à votre question, vous souhaitez utiliser le terme epsilon. Plus précisément, ce n'est machine epsilonque l'usage courant qui laisse tomber la "machine" et n'utilise que epsilon.

En regardant dans ma copie locale de float.hje vois:

#define DBL_EPSILON     2.2204460492503131e-016 /* smallest such that 1.0+DBL_EPSILON != 1.0 */  
#define FLT_EPSILON     1.192092896e-07F        /* smallest such that 1.0+FLT_EPSILON != 1.0 */  
#define LDBL_EPSILON    DBL_EPSILON             /* smallest such that 1.0+LDBL_EPSILON != 1.0 */

Et les commentaires associés montrent clairement que epsilon est le terme auquel vous faites référence.

Mais nous pouvons également nous fier à d'autres références externes pour vérifier qu'il epsilons'agit du terme correct. Voir ici , ici , ici , et enfin cette combinaison de balises de requête SO . Je n'ai pas pu trouver une référence directe à la norme IEEE 754 pour citer.


Vous ne l'avez pas demandé, mais j'ai trouvé cette référence très pertinente par rapport à l'exemple que vous avez fourni pour clarifier votre question.

Jetez un œil à cet article de blog de Bruce Dawson de Valve sur la comparaison des valeurs à virgule flottante pour savoir pourquoi vous ne souhaitez pas utiliser la comparaison que vous avez suggérée.

Il y a beaucoup d'informations dans cet article, mais c'est l'extrait de code le plus pertinent à partir de là:

Si la comparaison des flottants pour l'égalité est une mauvaise idée, pourquoi ne pas vérifier si leur différence se situe dans certaines limites d'erreur ou dans la valeur epsilon, comme ceci:

bool isEqual = fabs(f1 – f2) <= epsilon;

Avec ce calcul, nous pouvons exprimer le concept de deux flotteurs suffisamment proches pour que nous voulons les considérer comme égaux. Mais quelle valeur devons-nous utiliser pour epsilon?
Compte tenu de notre expérimentation ci-dessus, nous pourrions être tentés d'utiliser l'erreur dans notre somme, qui était d'environ 1,19e-7f. En fait, il y a même une définition dans float.h avec cette valeur exacte, et elle s'appelle FLT_EPSILON.
De toute évidence, c'est tout. Les dieux du fichier d'en-tête ont parlé et FLT_EPSILON est le seul vrai epsilon!
Sauf que ce sont des ordures. Pour les nombres entre 1,0 et 2,0, FLT_EPSILON représente la différence entre les flottants adjacents. Pour les nombres inférieurs à 1,0, un epsilon de FLT_EPSILON devient rapidement trop grand, et avec des nombres suffisamment petits, FLT_EPSILON peut être plus grand que les nombres que vous comparez!

Dawson passe en revue plusieurs autres considérations sur les subtilités impliquées lors de la comparaison des flottants et du traitement de très petites valeurs comme celle-ci, donc je vous encourage à lire le reste de son article.


Vous voudrez peut-être clarifier la première partie de votre réponse: l'article de Bruce explique déjà pourquoi il ne faut pas utiliser un epsilon constant (comme ceux définis dans un fichier d'en-tête) pour la comparaison des tolérances. De plus, dans de nombreux cas, une erreur de quelques millions d'ULP n'est pas quelque chose à craindre, car dans la plupart des applications, nous nous soucions plus des chiffres significatifs que des erreurs dans les chiffres les moins significatifs, car la double précision donne déjà beaucoup plus de chiffres que nous nous en soucions.
rwong

@rwong - comme je l'ai lu, la question était d'identifier le terme correct à utiliser pour le nom d'une constante. C'est pourquoi j'ai fourni la référence float.h avec quelques autres pour usiner epsilon. L'article de Dawson est quelque chose que j'ai trouvé en recherchant la référence IEEE 754 et je pensais que c'était pertinent pour les PO simplest formulapour la comparaison. Beaucoup utilisent cette approche comme première tentative, et j'ai inclus l'article de Dawson parce qu'il va vraiment dans les nuances de la complexité de la comparaison. J'ai donc essayé de répondre directement à la question, puis de montrer pourquoi ne pas l'utiliser de cette façon.

5

Il s'agit d'une fonction d'erreur; l'erreur absolue est généralement appelée ε (epsilon) ou Δ x pour une certaine quantité x:

ε = | attendu - réel |

Δ x = | x 0 - x  |

L'erreur relative est parfois appelée η (eta):

η = | 1 - réel / attendu |

À des fins de programmation, absoluteErroret relativeError(ou certaines de leurs abréviations) sont plus descriptifs. Si vous voulez affirmer que l'erreur est inférieure à une certaine valeur, cette valeur sera simplement appelée seuil ou tolérance .

Voir:


3

Je l'appellerais "tolérance".

Ce n'est peut-être pas le terme mathématiquement correct, mais le simple fait que vous posiez la question m'implique que ni "delta" ni "epsilon" ne seraient un bon nom de variable à utiliser.

D'après mon expérience, il est préférable d'utiliser des noms d'identifiants qui ont du sens pour ceux qui liront réellement le code. À quoi sert un nom parfaitement correct s'il signifie que le lecteur doit le rechercher sur Wikipedia pour comprendre ce qu'il signifie?


+1. J'espère toujours que les gens poseront des questions à leurs collègues sur ces questions de dénomination et publieront ici.
MarkJ

6
-1, Mieux vaut apprendre les conventions que les éviter.
djechlin

+1 parce que c'est exactement la même raison pour laquelle j'ai posé cette question.
NobleUplift
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.