Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IComparer issue

I have a weird issue and I don't have a clue to track the reason. I will try to descript my issue clearly.

I have a RTree class, in this class, I want to compare two rectanlge (here I called envelope, it contains minX, minY, maxX, maxY), so we have a comparer class as following:

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;
    }
}

With this comparer, we can maintain a ArrayList of envelope and sort it easily, the envelopes are randomly added. When we call the following code and we met the

Unable to sort because the IComparer.Compare() method returns inconsistent results. Either a value does not compare equal to itself, or one value repeatedly compared to another value yields different results.

sortedChildBoundables.Sort(new AnonymousXComparerImpl());

Here is the weird part. This error only occurs in .net 4.0 which doesn't install the VistualStudio. If the machine installed the VS or .net 4.5, this issue cannot reproceduce again.

In this case, I cannot figure out why it happens. It will be great if you have any experience on debuging this kind of issue, I appreciate.

Thanks, Howard

like image 474
Howard Avatar asked May 08 '13 07:05

Howard


1 Answers

If e.g. ea.MinX is NaN, a will be NaN and both a > b and a < b will be false. This means, there are objects which compare equal to every other object.

You first have to decide, how you want objects containing NaN to be sorted.

An easy workaround might be to insert

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

As noted by @Seph and @Jeppe in comments, double.CompareTo does the right thing, so the last line can be replaced by return a.CompareTo(b);.

like image 172
Henrik Avatar answered Oct 21 '22 19:10

Henrik