2013-01-21 62 views
4

我與double[]做在C#中的一些統計操作(.NET 4)的CompareTo行爲,然後我發現CompareTo方法和double.NaN一些奇怪的行爲。當我嘗試這種代碼:爲double.NaN和double.NegativeInfinity

double.NaN.CompareTo(double.NegativeInfinity) //returns -1 

這意味着double.NaNdouble.NegativeInfinity更小!任何人都可以解釋爲什麼它是這樣的?

+0

那麼,什麼是你的問題? – Servy

+0

不,這意味着對於排序的情況,NaN被認爲小於負無窮大。當我將NegativeInfinity與null比較時,我會猜測相同的規則。 –

+0

除了「這是規格說明要做的事情」或者可能是一些瘋狂的猜測之外,你不可能得到任何答案。 – Servy

回答

7

CompareTo不會告訴你一件事比另一件事小。它告訴您在訂購實例時,一個實例先於( - ),跟隨(+)或與(0)另一個實例可互換。

爲什麼這裏是真正達到在CLR原語的設計行爲。

IComparable的目的是爲了排序類型的實例。因此,對於NaN,這是一個有效的雙倍數值,決定在之前命令它的任何其他類型的實例

請注意,CompareTo不一定與數字大於/小於操作相同,在含義上或用途上。 CompareTo旨在提供雙倍可以採用的一組值的排序。例如,

double.NaN.CompareTo(double.NaN) 

將返回0,但

double.NaN == double.NaN 

是假的。同樣,

double.NaN.CompareTo(double.NegativeInfinity) 

返回-1,但

double.NaN < double.NegativeInfinity 

返回false。所以,CompareTo方法並不是說數學上double.NaN小於double.NegativeInfinity。事實上這個不到的運營商說這不是真的。但它是這樣說的,在訂購價值時,double.NaN首先來到。

以下是Double type LessThan Operator文檔的鏈接。並排閱讀以及IComparable.CompareTo的含義應該有助於澄清兩種方法試圖表達的差異。

6

double.NaN小於負無窮大。

從他們解釋的元數據信息;

public const double NegativeInfinity = -1.0/0.0 

public const double NaN = 0.0/0.0; 

Double.CompareTo()方法;

比較此實例的一個指定的雙精度浮點 數並返回一個整數,指示此 實例的值是否小於,小於指定的雙所述的 的值等於或大於精確的浮點數。

如果此實例不是數字(NAN)和價值是多少

Double.CompareTo()方法返回負整數

讓我們來看看這個樣本(這裏是一個DEMO);

void Main() 
{ 
    double a = double.NaN; 
    double b = double.NegativeInfinity; 
    Console.WriteLine(a.CompareTo(b)); 
} 

即使我們看看IL代碼,double.NaN代表與00 00 00 00 00 00 F8 FFdouble.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 
+0

呵呵MSDN不正確:Double.NaN.CompareTo(double.NaN)返回0,不是-1。 **幸運的是:** :-)好吧,我承認,當MSDN都是NaN時,MSDN告訴它爲0。 – atlaste

+0

@StefandeBruijn MSDN是對的。它表示**這個實例和值都不是數字(NaN),PositiveInfinity或NegativeInfinity。它返回零。**所以我認爲MSDN是正確的。 –

+0

是的,我首先用不完整的信息閱讀您的答案,然後在MSDN上看到它。你剛剛編輯它對我來說太快了;-) – atlaste

0

在一天結束時,將double.nan與任何數據進行比較是沒有意義的。但是如果你有一個雙精度列表並且想用它做一些事情,你會希望它們都在列表的最後,這樣你就可以首先完成所有有意義的工作,這樣當你看到第一個時,你就可以停下來。這就像一個列表,其中一些項目是空的,他們被推到最後。

其中double.nan發生的一些情況:

Dim d1 as double = 0/0 
Dim d2 as double = Double.PositiveInfinity/Double.PositiveInfinity 
Dim d3 as double = Double.PositiveInfinity/Double.NegativeInfinity 
Dim d4 as double = Double.PositiveInfinity/Double.PositiveInfinity 
Dim d5 as double = Double.PositiveInfinity/Double.NegativeInfinity