Comparando Doble.NaN consigo mismo


Estoy atascado tratando de averiguar por qué estas dos operaciones devuelven valores diferentes:

  1. Double.NaN == Double.NaN devuelve false
  2. Double.NaN.Equals(Double.NaN) devuelve true

Tengo la respuesta a la primera parte pero no a la segunda y no a "¿por qué estas dos comparaciones devuelven valores diferentes?"

Author: Community, 2013-01-22

4 answers

La razón de la diferencia es simple, si no obvia.

Si utiliza el operador de igualdad ==, entonces está utilizando la prueba IEEE para la igualdad.

Si estás usando el método Equals(object), entonces tienes que mantener el contrato de object.Equals(object). Al implementar este método (y el correspondiente método GetHashCode), debe mantener ese contrato, que es diferente del comportamiento de IEEE.

Si el contrato Equals no fue confirmado, entonces el comportamiento de las tablas hash se rompería.

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

Si !double.NaN.Equals(double.NaN), ¡nunca sacarías tu valor del diccionario!

Si la oración anterior no tiene sentido, entonces entienda que la mecánica del hash (utilizada en Dictionary<T,U>, HashSet<T>, etc) utilizan los métodos object.Equals(object) y object.GetHashCode() ampliamente, y se basan en las garantías de su comportamiento.

 30
Author: Drew Noakes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-22 13:06:16

En la parte inferior de la sección de observaciones Double.Equals, encontrará:

Si dos se duplican.Los valores NaN se prueban para la igualdad llamando al método Equals, el método devuelve true. Sin embargo, si dos valores NaN se prueban para la igualdad mediante el operador de igualdad, el operador devuelve false. Cuando se quiere determinar si el valor de un Doble no es un número (NaN), una alternativa es llamar al método isNaN.

 9
Author: Oded,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-22 12:50:04

Bueno, La respuesta de Oded es genial, pero quiero decir algo;

Cuando descompilo el método Double.Equals(), parece esto;

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

Así que ya que tenemos esto = Doble.NaN y obj = Doble.NaN

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

Así que basicamente es posible return ((obj == this) || true

Que es equvalente a

return ((obj == this) is true.

 3
Author: Soner Gönül,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:28:18

Si inspecciona Double.NaN;

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

El primero devuelve false ya que NaN no representa ningún número.

Un método u operador devuelve NaN cuando el resultado de una operación es indefinido. Por ejemplo, el resultado de dividir cero por cero es NaN

El segundo devuelve true cuando NaN la igualdad se implementa explícitamente en el método overloaded equals.

De msdn double.es igual a :

Si dos se duplican.Los valores NaN probado para la igualdad llamando a los Iguales método, el método devuelve true. Sin embargo, si se prueban dos valores de NaN para la igualdad mediante el uso del operador de igualdad, el operador devuelve falso. Cuando desea determinar si el valor de un Doble no es un número (NaN), una alternativa es llamar al método isNaN.

Esto se hace delibaretly para conformarse con IEC 60559:1989;

De acuerdo con IEC 60559: 1989, dos números de coma flotante con valores de NaN nunca son igual.Sin embargo, de acuerdo con las especificaciones del Sistema.Objeto:: Iguales método, es deseable anular este método para proporcionar valor semántica de igualdad. Desde el Sistema.ValueType proporciona esto funcionalidad a través del uso de la reflexión, la descripción para Objeto.Equals específicamente dice que los tipos de valor deben considerar sobreescribir la implementación de ValueType predeterminada para obtener un rendimiento aumentar. De hecho, de mirar la fuente de Sistema.ValueType:: Equals (línea 36 de clr\src \ BCL \ System \ ValueType.cs en el SSCLI), incluso hay un comentario del equipo de CLR Perf a la efecto del Sistema.ValueType:: Equivale a no ser rápido.

Refiérase a: http://blogs.msdn.com/b/shawnfa/archive/2004/07/19/187792.aspx

 3
Author: daryal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-22 13:02:16