Je sais que vous ne pouvez pas compter sur l'égalité entre les valeurs de type double ou décimal normalement, mais je me demande si 0 est un cas particulier.
Bien que je puisse comprendre les imprécisions entre 0,0000000000000001 et 0,0000000000000002, 0 lui-même semble assez difficile à gâcher car ce n'est rien. Si vous n'êtes imprécis sur rien, ce n'est plus rien.
Mais je ne connais pas grand-chose à ce sujet donc ce n'est pas à moi de le dire.
double x = 0.0;
return (x == 0.0) ? true : false;
Cela reviendra-t-il toujours vrai?
Réponses:
Il est prudent de s'attendre à ce que la comparaison retourne
true
si et seulement si la variable double a une valeur de exactement0.0
(ce qui dans votre extrait de code d'origine est, bien sûr, le cas). Ceci est cohérent avec la sémantique de l'==
opérateur.a == b
signifie "a
est égal àb
".Il n'est pas sûr (car ce n'est pas correct ) de s'attendre à ce que le résultat d'un calcul soit nul en arithmétique double (ou plus généralement en virgule flottante) chaque fois que le résultat du même calcul en mathématiques pures est nul. En effet, lorsque les calculs entrent dans le sol, une erreur de précision en virgule flottante apparaît - un concept qui n'existe pas dans l'arithmétique des nombres réels en mathématiques.
la source
Si vous avez besoin de faire beaucoup de comparaisons "d'égalité", il peut être judicieux d'écrire une petite fonction d'aide ou une méthode d'extension dans .NET 3.5 pour comparer:
Cela pourrait être utilisé de la manière suivante:
la source
Pour votre échantillon simple, ce test est correct. Mais qu'en est-il de ceci:
N'oubliez pas que .1 est une décimale répétitive en binaire et ne peut pas être représenté exactement. Ensuite, comparez cela à ce code:
Je vous laisse faire un test pour voir les résultats réels: vous aurez plus de chances de vous en souvenir de cette façon.
la source
À partir de l'entrée MSDN pour Double.Equals :
Voir également Double.Epsilon .
la source
x.Equals(y)
, alors(1/x).Equals(1/y)
, mais ce n'est pas le cas six
est0
ety
est1/Double.NegativeInfinity
. Ces valeurs sont déclarées égales, même si leurs réciproques ne le sont pas.x = 0
ety = 0
, et vous le trouverez toujours1/x != 1/y
.x
ety
comme typedouble
? Comment comparez-vous les résultats pour les rendre inégaux? Notez que 1 / 0.0 n'est pas NaN.1.0/0.0
ne parvient pas à être NaN comme il se doit, car la limite n'est pas unique. Deuxièmement, que les infinis se comparent égaux les uns aux autres, sans prêter aucune attention aux degrés d'infini)Le problème vient lorsque vous comparez différents types d'implémentation de valeur en virgule flottante, par exemple en comparant float avec double. Mais avec le même type, cela ne devrait pas être un problème.
Le problème est que le programmeur oublie parfois que le cast de type implicite (double en float) se produit pour la comparaison et cela entraîne un bogue.
la source
Si le nombre a été directement attribué au flottant ou au double, il est alors sûr de tester par rapport à zéro ou à tout nombre entier pouvant être représenté en 53 bits pour un double ou 24 bits pour un flottant.
Ou pour le dire autrement, vous pouvez toujours attribuer une valeur entière à un double, puis comparer le double au même entier et être assuré qu'il sera égal.
Vous pouvez également commencer par attribuer un nombre entier et faire en sorte que les comparaisons simples continuent de fonctionner en vous contentant d'ajouter, de soustraire ou de multiplier par des nombres entiers (en supposant que le résultat est inférieur à 24 bits pour un flottant et 53 bits pour un double). Ainsi, vous pouvez traiter les flottants et les doubles comme des entiers dans certaines conditions contrôlées.
la source
Non, ce n'est pas OK. Les valeurs dites dénormalisées (sous-normales), lorsqu'elles sont comparées à 0,0, seraient comparées comme fausses (non nulles), mais lorsqu'elles sont utilisées dans une équation, elles seraient normalisées (devenant 0,0). Ainsi, l'utiliser comme mécanisme pour éviter une division par zéro n'est pas sûr. Au lieu de cela, ajoutez 1.0 et comparez à 1.0. Cela garantira que toutes les sous-normales sont traitées comme nulles.
la source
Essayez ceci, et vous constaterez que == n'est pas fiable pour double / float.
double d = 0.1 + 0.2; bool b = d == 0.3;
Voici la réponse de Quora.
la source
En fait, je pense qu'il est préférable d'utiliser les codes suivants pour comparer une valeur double à 0,0:
Idem pour le flotteur:
la source