La bonne façon de comparer un Système.Double à '0' (un nombre, int?)
Désolé, ce peut être une simple question stupide, mais j'ai besoin de savoir pour être sûr.
J'ai cette if
expression,
void Foo()
{
System.Double something = GetSomething();
if (something == 0) //Comparison of floating point numbers with equality
//operator. Possible loss of precision while rounding value
{}
}
Est que l'expression d'égal à égal avec
void Foo()
{
System.Double something = GetSomething();
if (something < 1)
{}
}
? Parce que je pourrait avoir un problème, entrer dans le if
avec, par exemple, une valeur de 0,9.
// Comparison of floating point numbers with equality // operator.
Avez-vous vraiment besoin de préciser que? 🙂- Diable pas. Il y a un enfer de beaucoup de valeurs entre 0 et 1. Pourquoi ne pas simplement de le tester et de voir par vous-même?
- Je viens d'écrire la même chose que Resharper fait, pour montrer d'où mon accent est mis.
- Aussi, il y a beaucoup de nombres qui sont à moins de 0.
- double possible de Comparer les valeurs double en C#
Vous devez vous connecter pour publier un commentaire.
Bien, comment avez-vous besoin de la valeur à 0? Si vous passez par un grand nombre d'opérations en virgule flottante, qui dans "précision infinie" pourrait aboutir à 0, vous pourriez vous retrouver avec un résultat "très proche" de 0.
Généralement dans cette situation, vous voulez fournir une sorte de epsilon, et vérifier que le résultat est juste à l'intérieur de cette epsilon:
L'epsilon vous devez utiliser est spécifique à l'application, ça dépend de ce que vous faites.
Bien sûr, si le résultat doit être exactement zéro, alors qu'un simple contrôle d'égalité est très bien.
== 0
. Vous avez un littéral c'est assez constante 🙂Si
something
a été affecté par le résultat d'une opération autre qu'something = 0
alors il vaut mieux utiliser:Modifier: Ce code n'est pas correct. Epsilon est le plus petit nombre, mais pas tout à fait nulle. Lorsque vous souhaitez comparer un nombre à un autre nombre, vous avez besoin de penser à ce qu'est la tolérance acceptable. Disons que rien au-delà de .00001 vous ne se soucient pas. C'est le nombre que vous souhaitez utiliser. La valeur dépend du domaine. Cependant, c'est surtout certainement jamais en Double.Epsilon.
Math.Abs(0.1f - 0.1d) < double.Epsilon
estfalse
double d = Math.Sqrt(10100)*2; double a = Math.Sqrt(40400); if(Math.Abs(a - d) < double.Epsilon) { Console.WriteLine("true"); }
Votre
something
est undouble
, et vous avez correctement identifié que dans la lignenous avons un
double
sur le côté gauche (lhs) et unint
sur la droite (rhs).Mais il semble maintenant que vous pensez que la gauche sera converti en
int
, puis le==
signe de comparer deux nombres entiers. C'est pas ce qui se passe. La conversion dedouble
àint
est explicite et ne peut pas arriver "automatiquement".Plutôt l'inverse qui se produit. Le membre de droite est converti à
double
, puis le==
signe devient un test d'égalité entre deux doubles. Cette conversion est implicite (automatique).Il est considéré comme le meilleur (par certains) pour écrire
ou
car il est alors immédiat que vous comparez les deux doubles. Cependant, c'est juste une question de style et de lisibilité car le compilateur va faire la même chose en tout cas.
Il est également pertinent, dans certains cas, de mettre en place une "tolérance" à la manière de Jon Skeet réponse, mais que la tolérance serait une
double
trop. Il pourrait bien sûr être1.0
si vous le souhaitez, mais il n'a pas à être [le moins strictement positif] entier.Si vous voulez simplement supprimer l'avertissement, faites ceci:
Bien sûr, ce n'est qu'une solution valable si vous savez que la dérive n'est pas un sujet de préoccupation. Je le fais souvent pour vérifier si je suis sur le point de diviser par zéro.
Je ne pense que c'est égal, honnêtement. Considérer ses propres exemple: quelque chose = 0,9, ou 0.0004.
Dans le premier cas, il sera FAUX, dans le second cas, il sera VRAI. Traitant de ce types j'ai l'habitude de définir, pour moi, de précision, de pourcentage et de les comparer à l'intérieur de cette précision.
Dépend de vos besoins.
quelque chose comme...
Espère que cette aide.
Voici l'exemple de la présentation du problème (en LinQPad - si vous n'avez pas, il suffit d'utiliser
Console.Writeline
au lieu deDump
méthode):À la fois x et y sont théoriquement identique et égale à: 0.00001 mais en raison du manque de "précision infinie" ces valeurs sont légèrement différentes. Malheureusement un peu assez de retour
false
si l'on compare à 0 dans la manière habituelle.