Écriture d'une virgule flottante générale utile IsEqual
est très, très difficile, voire carrément impossible. Votre code actuel échouera gravement pour a==0
. La façon dont la méthode doit se comporter dans de tels cas est vraiment une question de définition, et on peut dire que le code serait mieux adapté au cas d'utilisation spécifique du domaine.
Pour ce genre de choses, vous vraiment, vraiment besoin une bonne suite de tests. C'est ainsi que je l'ai fait pour Le guide de la virgule flottante Voici ce que j'ai obtenu à la fin (code Java, qui devrait être assez facile à traduire) :
public static boolean nearlyEqual(float a, float b, float epsilon) {
final float absA = Math.abs(a);
final float absB = Math.abs(b);
final float diff = Math.abs(a - b);
if (a == b) { // shortcut, handles infinities
return true;
} else if (a == 0 || b == 0 || absA + absB < Float.MIN_NORMAL) {
// a or b is zero or both are extremely close to it
// relative error is less meaningful here
return diff < (epsilon * Float.MIN_NORMAL);
} else { // use relative error
return diff / (absA + absB) < epsilon;
}
}
Vous pouvez également trouver la suite de tests sur le site .
Annexe : Même code en c# pour les doubles (comme demandé dans les questions)
public static bool NearlyEqual(double a, double b, double epsilon)
{
const double MinNormal = 2.2250738585072014E-308d;
double absA = Math.Abs(a);
double absB = Math.Abs(b);
double diff = Math.Abs(a - b);
if (a.Equals(b))
{ // shortcut, handles infinities
return true;
}
else if (a == 0 || b == 0 || absA + absB < MinNormal)
{
// a or b is zero or both are extremely close to it
// relative error is less meaningful here
return diff < (epsilon * MinNormal);
}
else
{ // use relative error
return diff / (absA + absB) < epsilon;
}
}
1 votes
Quelle est votre question, exactement ?
0 votes
Quelqu'un peut-il indiquer (ou montrer) de bonnes fonctions générales de comparaison de valeurs en virgule flottante en C# pour comparer des valeurs en virgule flottante ? Le problème est que beaucoup de personnes ont montré des réponses partielles. Je suis à la recherche de quelque chose de plus complet.
2 votes
C'est dangereux, cela prétend qu'il y a un résultat significatif alors que les chiffres sont insignifiants. Faites attention au post de Philip.
1 votes
@Hans Passant - Je ne vois pas en quoi le post de Philip est utile. Je ne prétends pas que la fonction que j'ai trouvée est bonne ou correcte ; je cherche de l'aide à ce sujet.
0 votes
@NullUserException - Merci d'avoir ajouté le tag c#. Je ne sais pas comment j'ai pu le manquer.
1 votes
En posant des questions sur les comparaisons d'égalité en virgule flottante précédemment sur SO, On m'a donné ce conseil : "La question est la suivante : voulez-vous vraiment/avez-vous besoin de faire des tests d'égalité sur des valeurs à virgule flottante ? Vous devriez peut-être revoir la conception de vos algorithmes." En d'autres termes, le fait de ne pas avoir à effectuer une telle comparaison vous dispense de vous soucier de la manière de la réaliser correctement.
0 votes
@stakx Je suis arrivé sur ce site par Google et j'avais la même question. Je veux comparer des coordonnées de latitude et de longitude. Celles-ci se présentent sous la forme de nombres décimaux positifs et négatifs - sauf que l'on ne peut pas les traiter comme des
decimal
ou il tronque le point décimal si vous le stockez dans un champ décimal de la base de données (ce qui m'a paru bizarre en soi). Je suis donc coincé avec des doubles et des flottants comme Kevin l'était.0 votes
Duplicata potentiel - stackoverflow.com/questions/30727449/comparaison-de-deux-décimaux