System.Double.CompareTo 方法
本文提供了此 API 参考文档的补充说明。
CompareTo(Double) 方法
值必须相同,才能被视为相等。 特别是当浮点值依赖于多个数学运算时,它们通常会失去精度,并且它们的值几乎完全相同,但最小有效位数除外。 因此,有时方法的 CompareTo 返回值似乎令人吃惊。 例如,乘以特定值,后跟相同值的除法应生成原始值。 但是,在下面的示例中,计算值原来大于原始值。 使用“R” 标准数字格式字符串 显示这两个值的所有有效数字表示计算值与其最小有效位数中的原始值不同。 有关处理此类比较的信息,请参阅方法的 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
此方法实现 System.IComparable<T> 接口并比方法稍好 Double.CompareTo 一些,因为它不必将 value
参数转换为对象。
请注意,尽管值 NaN 不等于另一个值为 NaN (偶数本身)的对象,但 IComparable<T> 接口需要 A.CompareTo(A)
返回零。
CompareTo(Object) 方法
参数 value
必须是 null
或实例 Double
;否则,将引发异常。 无论其值如何,任何实例 Double都被视为大于 null
。
值必须相同,才能被视为相等。 特别是当浮点值依赖于多个数学运算时,它们通常会失去精度,并且它们的值几乎完全相同,但最小有效位数除外。 因此,有时方法的 CompareTo 返回值似乎令人吃惊。 例如,乘以特定值,后跟相同值的除法应生成原始值。 但是,在下面的示例中,计算值原来大于原始值。 使用“R” 标准数字格式字符串 显示这两个值的所有有效数字表示计算值与其最小有效位数中的原始值不同。 有关处理此类比较的信息,请参阅方法的 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
此方法实现以支持 IComparable 接口。 请注意,尽管接口不被视为等于另一个 NaNNaN (甚至本身),但 IComparable 接口需要 A.CompareTo(A)
返回零。
扩大转换
根据编程语言,可以编码 CompareTo 参数类型比实例类型少(较窄)的方法。 这是可能的,因为一些编程语言执行隐式扩大转换,该转换将参数表示为一个类型,其位数与实例数相同。
例如,假设实例类型为 Double ,参数类型为 Int32. Microsoft C# 编译器生成用于将参数值表示为 Double 对象的指令,然后生成一个 Double.CompareTo(Double) 方法,该方法比较实例的值和参数的扩大表示形式。
请参阅编程语言的文档,以确定其编译器是否执行数字类型的隐式扩展转换。 有关详细信息,请参阅 类型转换表 主题。
比较中的精度
超出记录精度的浮点数的精度特定于 .NET 的实现和版本。 因此,两个特定数字的比较可能会在 .NET 的版本之间发生更改,因为数字的内部表示形式的精度可能会更改。