Hos*_*Rad 5 c# double icomparable nan infinity
我在C#(.Net 4)中做了一些统计操作,double[]然后我发现了一些奇怪的CompareTo方法和方法double.NaN.当我尝试这段代码时:
double.NaN.CompareTo(double.NegativeInfinity) //returns -1
Run Code Online (Sandbox Code Playgroud)
它意味着double.NaN甚至比double.NegativeInfinity!任何人都能解释为什么会这样吗?
CompareTo并没有告诉你一件事比另一件小.它告诉你一个实例在( - )之后,跟随(+)或在订购实例时可以与(0)另一个实例互换.
这里的原因实际上取决于CLR中基元的设计行为.
IComparable的目的是为一个类型的实例排序.因此,对于NaN,一个有效的double值,决定在该类型的任何其他实例之前对其进行排序.
请注意,CompareTo不一定是相同的,在含义上或在预期用途中,作为大于/小于操作的数字.CompareTo旨在提供双倍可以承担的值集合的排序.例如,
double.NaN.CompareTo(double.NaN)
Run Code Online (Sandbox Code Playgroud)
将返回0.但是
double.NaN == double.NaN
Run Code Online (Sandbox Code Playgroud)
是假的.同样,
double.NaN.CompareTo(double.NegativeInfinity)
Run Code Online (Sandbox Code Playgroud)
返回-1,但是
double.NaN < double.NegativeInfinity
Run Code Online (Sandbox Code Playgroud)
返回false.因此,CompareTo方法并不是说数学上是double.NaN小于double.NegativeInfinity.事实上,小于运营商说这不是真的.但是它说,在订购价值时,double.NaN首先出现.
这里是Double类型的LessThan操作员文档的链接.同时阅读IComparable.CompareTo的含义应该有助于澄清两种方法试图表达的差异.
double.NaN 小于负无穷大.
从元数据信息中他们解释说;
public const double NegativeInfinity = -1.0 / 0.0
public const double NaN = 0.0 / 0.0;
Run Code Online (Sandbox Code Playgroud)
将此实例与指定的双精度浮点数进行比较,并返回一个整数,该整数指示此实例的值是否小于,等于或大于指定的双精度浮点数的值.
如果此实例不是数字(NaN)且值是数字
Double.CompareTo()方法返回一个负整数
我们来看看这个样本(这是一个DEMO);
void Main()
{
double a = double.NaN;
double b = double.NegativeInfinity;
Console.WriteLine(a.CompareTo(b));
}
Run Code Online (Sandbox Code Playgroud)
即使我们查看IL代码,double.NaN代表00 00 00 00 00 00 F8 FF并double.NegativeInfinity代表00 00 00 00 00 00 F0 FF;
IL_0000: ldc.r8 00 00 00 00 00 00 F8 FF
IL_0009: stloc.0
IL_000A: ldc.r8 00 00 00 00 00 00 F0 FF
IL_0013: stloc.1
IL_0014: ldloca.s 00
IL_0016: ldloc.1
IL_0017: call System.Double.CompareTo
IL_001C: call System.Console.WriteLine
Run Code Online (Sandbox Code Playgroud)