Métodos System.Double.CompareTo

En este artículo se proporcionan comentarios adicionales a la documentación de referencia de esta API.

Método CompareTo(Double)

Los valores deben ser idénticos para considerarse iguales. Especialmente cuando los valores de punto flotante dependen de varias operaciones matemáticas, es habitual que pierdan precisión y que sus valores sean casi idénticos, excepto por sus dígitos menos significativos. Debido a esto, el valor devuelto del CompareTo método a veces puede parecer sorprendente. Por ejemplo, la multiplicación por un valor determinado seguido de la división por el mismo valor debe generar el valor original. Sin embargo, en el ejemplo siguiente, el valor calculado resulta ser mayor que el valor original. Mostrar todos los dígitos significativos de los dos valores mediante la cadena de formato numérico estándar "R" indica que el valor calculado difiere del valor original en sus dígitos menos significativos. Para obtener información sobre cómo controlar estas comparaciones, vea la sección Comentarios del Equals(Double) método .

using System;

public class Example
{
    public static void Main()
    {
        double value1 = 6.185;
        double value2 = value1 * .1 / .1;
        Console.WriteLine("Comparing {0} and {1}: {2}\n",
                          value1, value2, value1.CompareTo(value2));
        Console.WriteLine("Comparing {0:R} and {1:R}: {2}",
                          value1, value2, value1.CompareTo(value2));
    }
}
// The example displays the following output:
//       Comparing 6.185 and 6.185: -1
//
//       Comparing 6.185 and 6.1850000000000005: -1
let value1 = 6.185
let value2 = value1 * 0.1 / 0.1
printfn $"Comparing {value1} and {value2}: {value1.CompareTo value2}\n"
printfn $"Comparing {value1:R} and {value2:R}: {value1.CompareTo value2}"
// The example displays the following output:
//       Comparing 6.185 and 6.185: -1
//
//       Comparing 6.185 and 6.1850000000000005: -1
Module Example
   Public Sub Main()
       Dim value1 As Double = 6.185
       Dim value2 As Double = value1 * .1 / .1
       Console.WriteLine("Comparing {0} and {1}: {2}",
                         value1, value2, value1.CompareTo(value2))
       Console.WriteLine()
       Console.WriteLine("Comparing {0:R} and {1:R}: {2}",
                         value1, value2, value1.CompareTo(value2))
   End Sub
End Module
' The example displays the following output:
'       Comparing 6.185 and 6.185: -1
'       
'       Comparing 6.185 and 6.1850000000000005: -1

Este método implementa la System.IComparable<T> interfaz y funciona ligeramente mejor que el Double.CompareTo método porque no tiene que convertir el value parámetro en un objeto.

Tenga en cuenta que, aunque un objeto cuyo valor no se NaN considera igual a otro objeto cuyo valor es NaN (incluso en sí mismo), la IComparable<T> interfaz requiere que A.CompareTo(A) devuelva cero.

Método CompareTo(Object)

El value parámetro debe ser null o una instancia de Double; de lo contrario, se produce una excepción. Cualquier instancia de Double, independientemente de su valor, se considera mayor que null.

Los valores deben ser idénticos para considerarse iguales. Especialmente cuando los valores de punto flotante dependen de varias operaciones matemáticas, es habitual que pierdan precisión y que sus valores sean casi idénticos, excepto por sus dígitos menos significativos. Debido a esto, el valor devuelto del CompareTo método a veces puede parecer sorprendente. Por ejemplo, la multiplicación por un valor determinado seguido de la división por el mismo valor debe generar el valor original. Sin embargo, en el ejemplo siguiente, el valor calculado resulta ser mayor que el valor original. Mostrar todos los dígitos significativos de los dos valores mediante la cadena de formato numérico estándar "R" indica que el valor calculado difiere del valor original en sus dígitos menos significativos. Para obtener información sobre cómo controlar estas comparaciones, vea la sección Comentarios del Equals(Double) método .

using System;

public class Example3
{
    public static void Main()
    {
        double value1 = 6.185;
        object value2 = value1 * .1 / .1;
        Console.WriteLine("Comparing {0} and {1}: {2}\n",
                          value1, value2, value1.CompareTo(value2));
        Console.WriteLine("Comparing {0:R} and {1:R}: {2}",
                          value1, value2, value1.CompareTo(value2));
    }
}
// The example displays the following output:
//       Comparing 6.185 and 6.185: -1
//
//       Comparing 6.185 and 6.1850000000000005: -1
let value1 = 6.185
let value2 = value1 * 0.1 / 0.1 |> box
printfn $"Comparing {value1} and {value2}: {value1.CompareTo value2}\n"
printfn $"Comparing {value1:R} and {value2:R}: {value1.CompareTo value2}"
// The example displays the following output:
//       Comparing 6.185 and 6.185: -1
//
//       Comparing 6.185 and 6.1850000000000005: -1
Module Example2
   Public Sub Main()
       Dim value1 As Double = 6.185
       Dim value2 As Object = value1 * .1 / .1
       Console.WriteLine("Comparing {0} and {1}: {2}",
                         value1, value2, value1.CompareTo(value2))
       Console.WriteLine()
       Console.WriteLine("Comparing {0:R} and {1:R}: {2}",
                         value1, value2, value1.CompareTo(value2))
   End Sub
End Module
' The example displays the following output:
'       Comparing 6.185 and 6.185: -1
'       
'       Comparing 6.185 and 6.1850000000000005: -1

Este método se implementa para admitir la IComparable interfaz . Tenga en cuenta que, aunque NaN no se considera igual a otro NaN (incluso a sí mismo), la IComparable interfaz requiere que A.CompareTo(A) devuelva cero.

Conversiones de ampliación

En función del lenguaje de programación, puede ser posible codificar un CompareTo método en el que el tipo de parámetro tenga menos bits (es más estrecho) que el tipo de instancia. Esto es posible porque algunos lenguajes de programación realizan una conversión de ampliación implícita que representa el parámetro como un tipo con tantos bits como la instancia.

Por ejemplo, supongamos que el tipo de instancia es Double y el tipo de parámetro es Int32. El compilador de Microsoft C# genera instrucciones para representar el valor del parámetro como un Double objeto y, a continuación, genera un Double.CompareTo(Double) método que compara los valores de la instancia y la representación ampliada del parámetro.

Consulte la documentación del lenguaje de programación para determinar si su compilador realiza conversiones implícitas de ampliación de tipos numéricos. Para obtener más información, vea el tema Tablas de conversión de tipos.

Precisión en comparaciones

La precisión de los números de punto flotante más allá de la precisión documentada es específica de la implementación y la versión de .NET. Por lo tanto, una comparación de dos números concretos podría cambiar entre versiones de .NET porque la precisión de la representación interna de los números podría cambiar.