42 votes

Comparaison de Double.NaN avec lui-même

Je suis bloqué en essayant de trouver pourquoi ces deux opérations renvoient des valeurs différentes :

  1. Double.NaN == Double.NaN renvoie à false
  2. Double.NaN.Equals(Double.NaN) renvoie à true

J'ai le respuesta à la première partie mais pas à la seconde et pas à "pourquoi ces deux comparaisons retournent des valeurs différentes".

36voto

Drew Noakes Points 69288

La raison de cette différence est simple, voire évidente.

Si vous utilisez l'opérateur d'égalité == alors vous utilisez le test d'égalité de l'IEEE.

Si vous utilisez le Equals(object) vous devez alors gérer le contrat de la méthode object.Equals(object) . Lorsque vous implémentez cette méthode (et la méthode correspondante GetHashCode ), vous devez maintenir ce contrat, ce qui est différent du comportement de l'IEEE.

Si le Equals n'était pas respecté, le comportement des tables de hachage serait rompu.

var map = new Dictionary<double,string>();
map[double.NaN] = "NaN";
var s = map[double.NaN];

Si !double.NaN.Equals(double.NaN) vous ne sortiriez jamais votre valeur du dictionnaire !

Si la phrase précédente n'a pas de sens, comprenez que la mécanique du hachage (utilisée dans Dictionary<T,U> , HashSet<T> etc.) utilisent à la fois le object.Equals(object) y object.GetHashCode() et s'appuient sur des garanties de leur comportement.

10voto

Oded Points 271275

Tout en bas de la section des remarques de Double.Equals vous trouverez :

Si l'on vérifie l'égalité de deux valeurs Double.NaN en appelant la méthode Equals, celle-ci renvoie un résultat vrai. Toutefois, si l'égalité de deux valeurs NaN est vérifiée à l'aide de l'opérateur d'égalité, celui-ci renvoie un résultat faux. Lorsque vous souhaitez déterminer si la valeur d'un Double n'est pas un nombre (NaN), une alternative consiste à appeler la méthode IsNaN.

3voto

daryal Points 8211

Si vous contrôlez Double.NaN ;

    // Summary:
    //     Represents a value that is not a number (NaN). This field is constant.
    public const double NaN = 0.0 / 0.0;

le premier renvoie faux car NaN ne représente aucun nombre.

Une méthode ou un opérateur renvoie NaN lorsque le résultat d'une opération est indéfini. Par exemple, le résultat de la division de zéro par zéro est NaN.

La seconde renvoie la vérité comme NaN L'égalité est implémentée de manière explicite dans la fonction surchargée equals méthode.

de msdn double.equals :

Si l'égalité de deux valeurs Double.NaN est testée en appelant la méthode Equals la méthode renvoie la valeur vraie. Toutefois, si l'égalité de deux valeurs NaN est testée l'égalité à l'aide de l'opérateur d'égalité, celui-ci renvoie un résultat faux. Lorsque vous voulez déterminer si la valeur d'un double n'est pas un nombre (NaN), un test d'égalité est nécessaire. un nombre (NaN), une alternative consiste à appeler la méthode IsNaN.

Cette mesure est prise délibérément pour se conformer aux règles de l'UE. IEC 60559:1989 ;

Selon la norme IEC 60559:1989, deux nombres à virgule flottante ayant pour valeur NaN ne sont jamais égaux. NaN ne sont jamais égaux. Toutefois, selon la spécification de la fonction System.Object::Equals il est souhaitable de surcharger cette méthode pour fournir une sémantique d'égalité des valeurs. sémantique de l'égalité des valeurs. Puisque System.ValueType fournit cette fonctionnalité grâce à l'utilisation de Reflection, la description d'Object. Object.Equals indique spécifiquement que les types de valeur doivent envisager de remplacer l'implémentation ValueType par défaut afin d'améliorer les performances. performances. En fait, en regardant la source de System.ValueType::Equals (ligne 36 de clr \src\BCL\System\ValueType.cs dans le SSCLI), il y a même un commentaire de l'équipe CLR Perf à propos de l'effet de System.ValueType::Equals n'étant pas rapide.

se référer : http://blogs.msdn.com/b/shawnfa/archive/2004/07/19/187792.aspx

3voto

Soner Gönül Points 35739

Bien, La réponse d'Oded c'est génial mais je veux dire quelque chose ;

Quand je décompile Double.Equals() méthode, ça ressemble à ça ;

public bool Equals(double obj)
{
    return ((obj == this) || (IsNaN(obj) && IsNaN(this)));
}

Donc, puisque nous avons ceci = Double.NaN y obj = Double.NaN

(IsNaN(obj)) and (IsNaN(this)) returns `true`.

En gros, il s'agit de return ((obj == this) || true

ce qui équivaut à

return ((obj == this) es true .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X