La sagesse courante selon laquelle les nombres à virgule flottante ne peuvent pas être comparés pour l'égalité est inexacte. Les nombres à virgule flottante ne sont pas différents des entiers: si vous évaluez "a == b", vous obtiendrez vrai si ce sont des nombres identiques et faux sinon (étant entendu que deux NaN ne sont bien sûr pas des nombres identiques).
Le vrai problème est le suivant: si j'ai fait quelques calculs et que je ne suis pas sûr que les deux chiffres que je dois comparer sont exactement corrects, alors quoi? Ce problème est le même pour les virgules flottantes que pour les entiers. Si vous évaluez l'expression entière "7/3 * 3", elle ne sera pas comparable à "7 * 3/3".
Supposons donc que nous ayons demandé "Comment comparer les entiers pour l'égalité?" Dans une telle situation. Il n'y a pas de réponse unique; ce que vous devez faire dépend de la situation spécifique, notamment du type d'erreurs que vous avez et de ce que vous souhaitez obtenir.
Voici quelques choix possibles.
Si vous voulez obtenir un résultat "vrai" si les nombres mathématiquement exacts sont égaux, vous pouvez essayer d'utiliser les propriétés des calculs que vous effectuez pour prouver que vous obtenez les mêmes erreurs dans les deux nombres. Si cela est possible et que vous comparez deux nombres qui résultent d'expressions qui donneraient des nombres égaux s'ils étaient calculés exactement, alors vous obtiendrez «vrai» de la comparaison. Une autre approche consiste à analyser les propriétés des calculs et à prouver que l'erreur ne dépasse jamais un certain montant, peut-être un montant absolu ou un montant relatif à l'une des entrées ou l'une des sorties. Dans ce cas, vous pouvez demander si les deux nombres calculés diffèrent d'au plus ce montant et renvoyer "vrai" s'ils se trouvent dans l'intervalle. Si vous ne pouvez pas prouver une erreur liée, vous pourriez deviner et espérer le meilleur. Une façon de deviner est d'évaluer de nombreux échantillons aléatoires et de voir quel type de distribution vous obtenez dans les résultats.
Bien sûr, puisque nous ne fixons l'exigence que vous devenez "vrai" que si les résultats mathématiquement exacts sont égaux, nous avons laissé ouverte la possibilité que vous obteniez "vrai" même s'ils sont inégaux. (En fait, nous pouvons satisfaire à l'exigence en retournant toujours "vrai". Cela rend le calcul simple mais n'est généralement pas souhaitable, donc je vais discuter de l'amélioration de la situation ci-dessous.)
Si vous voulez obtenir un résultat "faux" si les nombres mathématiquement exacts sont inégaux, vous devez prouver que votre évaluation des nombres donne des nombres différents si les nombres mathématiquement exacts sont inégaux. Cela peut être impossible à des fins pratiques dans de nombreuses situations courantes. Examinons donc une alternative.
Une condition utile pourrait être d'obtenir un résultat "faux" si les nombres mathématiquement exacts diffèrent de plus d'un certain montant. Par exemple, nous allons peut-être calculer où une balle lancée dans un jeu vidéo a voyagé, et nous voulons savoir si elle a frappé une batte. Dans ce cas, nous voulons certainement obtenir "vrai" si la balle frappe la batte, et nous voulons obtenir "faux" si la balle est loin de la batte, et nous pouvons accepter une réponse "vraie" incorrecte si la balle dans une simulation mathématiquement exacte a raté la chauve-souris, mais se situe à un millimètre près de la frappe. Dans ce cas, nous devons prouver (ou deviner / estimer) que notre calcul de la position de la balle et de la position de la batte a une erreur combinée d'au plus un millimètre (pour toutes les positions d'intérêt). Cela nous permettrait de toujours revenir "
Ainsi, la façon dont vous décidez quoi retourner lorsque vous comparez des nombres à virgule flottante dépend beaucoup de votre situation spécifique.
Quant à la façon dont vous allez prouver les limites d'erreur pour les calculs, cela peut être un sujet compliqué. Toute implémentation en virgule flottante utilisant la norme IEEE 754 en mode arrondi au plus proche renvoie le nombre à virgule flottante le plus proche du résultat exact pour toute opération de base (notamment multiplication, division, addition, soustraction, racine carrée). (En cas d'égalité, arrondissez pour que le bit faible soit égal.) (Faites particulièrement attention à la racine carrée et à la division; l'implémentation de votre langage peut utiliser des méthodes qui ne sont pas conformes à IEEE 754 pour celles-ci.) En raison de cette exigence, nous connaissons la l'erreur dans un seul résultat représente au plus la moitié de la valeur du bit le moins significatif. (Si c'était plus, l'arrondi serait allé à un nombre différent qui est dans la moitié de la valeur.)
Partir de là devient beaucoup plus compliqué; l'étape suivante exécute une opération où l'une des entrées a déjà une erreur. Pour les expressions simples, ces erreurs peuvent être suivies à travers les calculs pour atteindre une limite sur l'erreur finale. En pratique, cela ne se fait que dans quelques situations, comme le travail sur une bibliothèque de mathématiques de haute qualité. Et, bien sûr, vous avez besoin d'un contrôle précis sur exactement quelles opérations sont effectuées. Les langages de haut niveau donnent souvent beaucoup de mou au compilateur, vous ne savez donc peut-être pas dans quel ordre les opérations sont effectuées.
Il y a beaucoup plus qui pourrait être (et est) écrit sur ce sujet, mais je dois m'arrêter là. En résumé, la réponse est: il n'y a pas de routine de bibliothèque pour cette comparaison, car il n'y a pas de solution unique qui réponde à la plupart des besoins qui mérite d'être mise dans une routine de bibliothèque. (Si la comparaison avec un intervalle d'erreur relatif ou absolu vous suffit, vous pouvez le faire simplement sans routine de bibliothèque.)