Metody System.Single.CompareTo

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

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ę, a ich wartości są prawie identyczne, z wyjątkiem ich najmniej znaczących cyfr. Z tego powodu wartość CompareTo zwracana metody może wydawać się zaskakująca czasami. 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, ale w poniższym przykładzie obliczona wartość okazuje się być 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(Single) .

Mimo że 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(System.Object)

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

using System;

public class Example
{
   public static void Main()
   {
       float value1 = 16.5457f;
       float operand = 3.8899982f;
       object value2 = value1 * operand / operand;
       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 16.5457 and 16.5457: -1
//       
//       Comparing 16.5457 and 16.545702: -1
let value1 = 16.5457f
let operand = 3.8899982f
let value2 = box (value1 * operand / operand)
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 16.5457 and 16.5457: -1
//       
//       Comparing 16.5457 and 16.545702: -1
Module Example2
    Public Sub Main()
        Dim value1 As Single = 16.5457
        Dim value2 As Object = value1 * CSng(3.8899982) / CSng(3.8899982)
        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 16.5457 and 16.5457: -1
'       
'       Comparing 16.5457 and 16.545702: -1

Ta metoda jest implementowana w celu obsługi interfejsu IComparable .

CompareTo(System.Single)

Ta metoda implementuje System.IComparable<T> interfejs i działa nieco lepiej niż Single.CompareTo(Object) przeciążenie, ponieważ nie musi konwertować parametru value na obiekt.

using System;

public class Example2
{
   public static void Main()
   {
       float value1 = 16.5457f;
       float operand = 3.8899982f;
       float value2 = value1 * operand / operand;
       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 16.5457 and 16.5457: -1
//       
//       Comparing 16.5457 and 16.545702: -1
let value1 = 16.5457f
let operand = 3.8899982f
let value2 = value1 * operand / operand
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 16.5457 and 16.5457: -1
//       
//       Comparing 16.5457 and 16.545702: -1
Module Example
   Public Sub Main()
       Dim value1 As Single = 16.5457
       Dim value2 As Single = value1 * CSng(3.8899982) / CSng(3.8899982)
       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 16.5457 and 16.5457: -1
'       
'       Comparing 16.5457 and 16.545702: -1

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 Single , a typ parametru to Int32. Kompilator języka Microsoft C# generuje instrukcje reprezentujące wartość parametru jako Single obiekt, a następnie generuje metodę Single.CompareTo(Single) , 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.