2013-05-08 51 views
5

我有一個奇怪的問題,我沒有線索來追蹤原因。我會盡量清楚地描述我的問題。IComparer問題

我有一個RTREE類,在這個類,我想比較兩個rectanlge(這裏我叫信封,它包含了minX,MINY,maxX的,美星),所以我們有一個比較器類如下:

private class AnonymousXComparerImpl : IComparer 
{ 
    public AnonymousXComparerImpl() 
    { } 

    public int Compare(object o1, object o2) 
    { 
     IEnvelope ea = (IEnvelope)((IBoundable)o1).Bounds; 
     IEnvelope eb = (IEnvelope)((IBoundable)o2).Bounds; 
     double a = (ea.MinX + ea.MaxX)/2d; 
     double b = (eb.MinX + eb.MaxX)/2d; 
     return a > b ? 1 : a < b ? -1 : 0; 
    } 
} 

有了這個比較器,我們可以維護一個信封的ArrayList並輕鬆地排序,信封隨機添加。當我們調用下面的代碼,我們遇到的

無法排序因爲IComparer.Compare()方法返回 不一致的結果。要麼一個值不會與自身等值, 或者一個值反覆與另一個值進行比較會得到不同的 結果。

sortedChildBoundables.Sort(new AnonymousXComparerImpl()); 

這裏是怪異的一部分。此錯誤只出現在不安裝VistualStudio的.net 4.0中。如果機器安裝了VS或.net 4.5,則此問題無法再次重新生成。

在這種情況下,我不知道爲什麼會發生。如果你有任何關於調試這類問題的經驗,那將是非常棒的,我很欣賞。

感謝, 霍華德

+0

我能想到的唯一的事情就是浮點問題,意思是相同的項目並不完全匹配,不知道爲什麼它會特定於v4。你是否嘗試過強化四捨五入? – 2013-05-08 07:52:51

+0

嘗試使用'decimal'數據類型代替雙精度 – Saravanan 2013-05-08 07:55:51

+0

有沒有其他線程參與?此外,這個線程可能是有趣的:http://stackoverflow.com/questions/6683059/are-floating-point-numbers-consistent-in-c-can-they-be – 2013-05-08 07:56:42

回答

5

如果如ea.MinXNaN,a將是NaN並且a > ba < b都將是false。這意味着,有一些對象與其他對象相等。

你首先要決定,你想怎麼包含NaN對象進行排序。

一個簡單的解決辦法可能是插入

if (double.IsNaN(a)) a = 0.0; 
if (double.IsNaN(b)) b = 0.0; 

正如在評論中所指出的@Seph和@Jeppe,double.CompareTo做正確的事,所以最後一行可以通過return a.CompareTo(b);更換。

+0

+1這聽起來似乎合理 - 儘管我不確定爲什麼.Net版本的結果會有所不同。但是,如果數據中有*可以是NaN(並且OP說可以),那麼肯定會導致觀察到的問題。 – 2013-05-08 09:19:53

+0

這很有道理,請允許我暫時擱置此線程,稍後再標記爲答案。非常感謝。 – Howard 2013-05-08 09:38:10

+2

@MthetheWWatson - 也許新版本中的Sort功能不會做不必要的比較,因此無法檢測到不一致。 – Henrik 2013-05-08 11:24:46

0

一個可能的原因是您的信息在比較過程中實際發生了變化。

如果你在後臺線程來排序,如果比較請求兩次當同一項目獲得不同的值,你一定會得到這個錯誤。

如果您的主線程在比較運行時更新其中一個值(可能是通過數據綁定),例如。

請確保您緩存了比較值,以便始終返回一致的結果。或者接受這個錯誤可能會不時發生,如果有錯誤可以重做。

這也將解釋你的機器/操作系統依賴的感覺。多線程問題根據軟件和硬件的不同而不同。