Est la vérification d'un lit double pour l'égalité jamais à l'abri?
J'ai le code suivant:
double x = 0;
{ ...do stuff ...}
if(x == 0){
}
J'ai toujours été enseigné que vous ne devriez pas vérifier les flotteurs pour l'égalité. Vérifie pour voir si elle est égale à zéro différent?
- je ne comprenez pas, si vous init x 0 pourquoi il n'est pas bon de vérifier si 0 ? 0 est une valeur valide pour le double
- Les nombres à virgule flottante ont beaucoup d'arrondi lorsque vous commencez à atteindre les limites. Même raison que si vous avez 3 chiffres en base dix, vous avez .004 et de diviser par trois, vous vous attendez .001, mais qui sait ce qui se passe.
- Thomas corrections: C'est techniquement pas d'arrondi, mais l'imprécision due à la précision limitée et la nature binaire de la flotte.
- Quelqu'un devrait résumer toutes les réponses à cette question.
Vous devez vous connecter pour publier un commentaire.
La raison pour laquelle vous ne devriez pas vérifier les flotteurs pour l'égalité, c'est que les nombres à virgule flottante ne sont pas parfaitement précis, il y a quelques inexactitudes dans le stockage avec des chiffres, comme ceux qui s'étendait aussi loin dans la mantisse et de répéter les décimales (notez que je parle de répéter décimales en base 2). Vous pouvez penser de cette imprécision que "arrondissant". Les chiffres qui s'étendent au-delà de la précision du nombre à virgule flottante sont tronqués, effectivement arrondi vers le bas.
Si il n'a pas changé, elle permet de conserver l'égalité. Cependant, si vous en changez, même légèrement, vous ne devriez probablement pas utiliser les égalités, mais plutôt une gamme comme
(x < 0.0001 && x > -.0001)
.En bref: tant que vous ne jouez pas avec x à un niveau très faible, c'est OK.
3/2
est1
3/2
est1
parce que des "imprécisions dans l'entier des représentations"? Voir Ce que Tout informaticien Devez Savoir à Propos de l'Arithmétique à virgule Flottante pg173, ou WikipédiaC'est sûr, si le 0 vous essayez d'attraper est à l'origine d'0 à l'initialisation. Cependant, il n'est pas sûr si vous attendez un 0 à partir d'une opération mathématique.
Vous encore ne doit pas vérifier pour voir si elle est égale à zéro. Il suffit de vérifier pour voir si il est proche de zéro.
if (value >= target * (1 - epsilon) && value <= target * (1 + epsilon ))
Cela est particulièrement vrai lorsque les valeurs peuvent varier sur une large gamme.si vous définissez vous-même et que vous désirez voir si elle a jamais changé, vous pouvez en toute sécurité pour vérifier l'égalité (comme l'utilisation d'une sentinelle de la valeur) mais NaN est plus sûr pour les choses comme ça
double a de positif et de négatif à zéro.
==
entre zéro positif et négatif de zéro renvoie la valeur false. Aussi,==
entre deux NaNs renvoie la valeur false.