Методы System.Single.CompareTo
В этой статье приводятся дополнительные замечания к справочной документации по этому API.
Значения должны быть идентичными, которые считаются равными. Особенно, если значения с плавающей запятой зависят от нескольких математических операций, они часто теряют точность и для их значений почти идентичны, за исключением их наименее значимых цифр. Из-за этого возвращаемое значение CompareTo метода может показаться удивительным в разы. Например, умножение на определенное значение, за которым следует деление по тому же значению, должно производить исходное значение, но в следующем примере вычисляемое значение оказывается больше исходного значения. Отображение всех значимых цифр двух значений с помощью строки стандартного числового формата R указывает на то, что вычисляемое значение отличается от исходного значения в его наименее значимых цифрах. Сведения об обработке таких сравнений Equals(Single) см. в разделе "Примечания" метода.
Хотя объект, значение NaN которого не считается равным другому объекту, значение NaN которого (даже само по себе), IComparable<T> интерфейс требует, чтобы A.CompareTo(A)
возвращать ноль.
CompareTo(System.Object)
Параметр value
должен быть null
или экземпляром Single; в противном случае создается исключение. Любой Singleэкземпляр , независимо от его значения, считается больше 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
Этот метод реализуется для поддержки IComparable интерфейса.
CompareTo(System.Single)
Этот метод реализует System.IComparable<T> интерфейс и выполняет немного лучше, чем перегрузка Single.CompareTo(Object) , так как не требуется преобразовывать value
параметр в объект.
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
Расширение преобразований
В зависимости от языка программирования можно закодировать CompareTo метод, в котором тип параметра имеет меньше битов (является более узким), чем тип экземпляра. Это возможно, так как некоторые языки программирования выполняют неявное расширение преобразования, представляющее параметр как тип с большим количеством битов, как экземпляр.
Например, предположим, что тип экземпляра имеет тип Single , а тип параметра — Int32. Компилятор Microsoft C# создает инструкции для представления значения параметра в качестве Single объекта, а затем создает Single.CompareTo(Single) метод, который сравнивает значения экземпляра и расширенный представление параметра.
Ознакомьтесь с документацией по языку программирования, чтобы определить, выполняет ли компилятор неявное расширение преобразований числовых типов. Дополнительные сведения см. в разделе "Таблицы преобразования типов".
Точность сравнения
Точность чисел с плавающей запятой за пределами документированной точности зависит от реализации и версии .NET. Следовательно, сравнение двух конкретных чисел может измениться между версиями .NET, так как точность внутреннего представления чисел может измениться.