Metody System.Double.CompareTo

Ten artykuł zawiera dodatkowe uwagi dotyczące dokumentacji referencyjnej dla tego interfejsu API.

CompareTo(Double) Metoda

Wartości muszą być identyczne, aby były uważane za równe. Szczególnie w przypadku, gdy wartości zmiennoprzecinkowe zależą od wielu operacji matematycznych, często zdarza się, że tracą precyzję i wartości są prawie identyczne, z wyjątkiem ich najmniej znaczących cyfr. Z tego powodu wartość CompareTo zwracana metody czasami może wydawać się zaskakująca. Na przykład mnożenie określonej wartości, po której następuje dzielenie przez tę samą wartość, powinno spowodować wygenerowanie oryginalnej wartości. Jednak w poniższym przykładzie obliczona wartość jest większa niż oryginalna wartość. Wyświetlanie wszystkich znaczących cyfr dwóch wartości przy użyciu standardowego ciągu formatu liczbowego "R" wskazuje, że obliczona wartość różni się od oryginalnej wartości w najmniej znaczących cyfrach. Aby uzyskać informacje na temat obsługi takich porównań, zobacz sekcję Uwagi metody Equals(Double) .

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

Ta metoda implementuje System.IComparable<T> interfejs i działa nieco lepiej niż Double.CompareTo metoda, ponieważ nie musi konwertować parametru value na obiekt.

Należy pamiętać, że chociaż obiekt, którego wartość nie jest NaN uznawana za równy innemu obiektowi, którego wartość jest NaN (nawet sama), IComparable<T> interfejs wymaga, aby zwracał A.CompareTo(A) zero.

CompareTo(Object) Metoda

Parametr value musi być null lub wystąpieniem Double; w przeciwnym razie zgłaszany jest wyjątek. Każde wystąpienie klasy Double, niezależnie od jego wartości, jest uznawane za większe niż null.

Wartości muszą być identyczne, aby były uważane za równe. Szczególnie w przypadku, gdy wartości zmiennoprzecinkowe zależą od wielu operacji matematycznych, często zdarza się, że tracą precyzję i wartości są prawie identyczne, z wyjątkiem ich najmniej znaczących cyfr. Z tego powodu wartość CompareTo zwracana metody czasami może wydawać się zaskakująca. Na przykład mnożenie określonej wartości, po której następuje dzielenie przez tę samą wartość, powinno spowodować wygenerowanie oryginalnej wartości. Jednak w poniższym przykładzie obliczona wartość jest większa niż oryginalna wartość. Wyświetlanie wszystkich znaczących cyfr dwóch wartości przy użyciu standardowego ciągu formatu liczbowego "R" wskazuje, że obliczona wartość różni się od oryginalnej wartości w najmniej znaczących cyfrach. Aby uzyskać informacje na temat obsługi takich porównań, zobacz sekcję Uwagi metody Equals(Double) .

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

Ta metoda jest implementowana w celu obsługi interfejsu IComparable . Należy pamiętać, że chociaż element NaN nie jest uważany za równy innemu NaN (nawet samemu sobie), IComparable interfejs wymaga, aby zwracał A.CompareTo(A) zero.

Konwersje rozszerzające

W zależności od języka programowania można kodować metodę CompareTo , w której typ parametru ma mniej bitów (jest węższy) niż typ wystąpienia. To jest możliwe, ponieważ w niektórych językach programowania jest wykonywana niejawna konwersja poszerzająca, która powoduje reprezentowanie parametru jako typu z taką samą liczbą bitów jak liczba bitów wystąpienia.

Załóżmy na przykład, że typ wystąpienia to Double , a typ parametru to Int32. Kompilator języka Microsoft C# generuje instrukcje reprezentujące wartość parametru jako Double obiekt, a następnie generuje metodę Double.CompareTo(Double) , która porównuje wartości wystąpienia i poszerzone reprezentacje parametru.

Sprawdź dokumentację języka programowania, aby określić, czy jego kompilator wykonuje niejawne poszerzenia konwersji dla typów liczbowych. Aby uzyskać więcej informacji, zobacz temat Tabele konwersji typów.

Precyzja w porównaniach

Precyzja liczb zmiennoprzecinkowych poza udokumentowaną precyzją jest specyficzna dla implementacji i wersji platformy .NET. W związku z tym porównanie dwóch konkretnych liczb może ulec zmianie między wersjami platformy .NET, ponieważ precyzja wewnętrznej reprezentacji liczb może ulec zmianie.