Metody System.Single.CompareTo
Ten artykuł zawiera dodatkowe uwagi dotyczące dokumentacji referencyjnej dla tego interfejsu API.
Wartości muszą być identyczne, aby można je było uznać 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 zwracana wartość metody CompareTo 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 ciągu "R" standardowego ciągu formatu liczbowego 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ść jest NaN, nie jest uznawany za równy innemu obiektowi, którego wartość jest NaN (nawet sam), interfejs IComparable<T> wymaga, aby A.CompareTo(A)
zwrócić zero.
CompareTo(System.Object)
Parametr value
musi być null
lub instancją Single; w przeciwnym razie zgłaszany jest wyjątek. Każde wystąpienie 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 {value1} and {value2}: {value1.CompareTo(value2)}");
Console.WriteLine();
Console.WriteLine($"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
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 interfejs System.IComparable<T> i działa nieco lepiej niż przeciążenie Single.CompareTo(Object), 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 {value1} and {value2}: {value1.CompareTo(value2)}");
Console.WriteLine();
Console.WriteLine($"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
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. Jest to możliwe, ponieważ niektóre języki programowania wykonują niejawną konwersję rozszerzającą, która reprezentuje parametr jako typ z tyloma bitami co wystąpienie.
Załóżmy na przykład, że typ wystąpienia jest Single, a typ parametru to Int32. Kompilator języka Microsoft C# generuje instrukcje reprezentujące wartość parametru jako obiekt Single, a następnie generuje metodę Single.CompareTo(Single), która porównuje wartości wystąpienia i poszerzone reprezentacje parametru.
Zapoznaj się z dokumentacją języka programowania, aby ustalić, czy kompilator wykonuje niejawne konwersje rozszerzające typy liczbowe. Aby uzyskać więcej informacji, zapoznaj się z tematem 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.