2013-05-08 108 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

一个可能的原因是您的信息在比较过程中实际发生了变化。

如果你在后台线程来排序,如果比较请求两次当同一项目获得不同的值,你一定会得到这个错误。

如果您的主线程在比较运行时更新其中一个值(可能是通过数据绑定),例如。

请确保您缓存了比较值,以便始终返回一致的结果。或者接受这个错误可能会不时发生,如果有错误可以重做。

这也将解释你的机器/操作系统依赖的感觉。多线程问题根据软件和硬件的不同而不同。