2013-05-08 15 views
5

Ich habe ein seltsames Problem und ich habe keine Ahnung, um den Grund zu verfolgen. Ich werde versuchen, mein Problem klar zu beschreiben.IComparer Ausgabe

ich eine RTree Klasse haben, in dieser Klasse, möchte ich zwei rectanlge vergleichen (ich hier genannt Umschlag, es enthält minX, minY, maxX, maxY), so haben wir eine comparer Klasse wie folgt:

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

Mit diesem Vergleich können wir eine ArrayList der Hülle pflegen und leicht sortieren, die Umschläge werden nach dem Zufallsprinzip hinzugefügt. Wenn wir rufen Sie den folgenden Code und wir trafen die

konnte nicht sortieren, weil die IComparer.Compare() -Methode inkonsistente Ergebnisse. Entweder vergleicht sich ein Wert nicht mit sich selbst, oder ein Wert, der wiederholt mit einem anderen Wert verglichen wird, ergibt andere Ergebnisse.

sortedChildBoundables.Sort(new AnonymousXComparerImpl()); 

Hier ist der seltsame Teil. Dieser Fehler tritt nur in .NET 4.0 auf, das das VisualStudio nicht installiert. Wenn der Computer VS oder .NET 4.5 installiert hat, kann dieses Problem nicht erneut auftreten.

In diesem Fall kann ich nicht herausfinden, warum es passiert. Es wird großartig sein, wenn Sie irgendwelche Erfahrung im Debuggen dieser Art von Problem haben, schätze ich.

Danke, Howard

+0

Das einzige, was ich hier denken kann, sind Gleitkomma-Probleme, was bedeutet, dass die Gleichheit für die gleichen Elemente nicht ganz übereinstimmt, keine Ahnung, warum es für v4 spezifisch wäre. Haben Sie versucht, ein Rundungsniveau durchzusetzen? –

+0

Versuchen Sie es mit dem Dezimal-Datentyp anstelle der Doppel – Saravanan

+0

Es gibt keine anderen Threads beteiligt sind dort? Auch dieser Thread könnte von Interesse sein: http://stackoverflow.com/questions/6683059/are-floating-point-numbers-consistent-in-c-can-they-be –

Antwort

5

Wenn z.B. ea.MinX ist NaN, a wird NaN sein und sowohl a > b als auch a < b werden false sein. Das heißt, es gibt Objekte, die mit jedem anderen Objekt gleich sind.

Zuerst müssen Sie entscheiden, wie Objekte mit NaN sortiert werden sollen.

Eine einfache Abhilfe könnte

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

Wie von @Seph und @Jeppe in Kommentare einfügen sein, double.CompareTo das Richtige tut, so dass die letzte Zeile durch return a.CompareTo(b); ersetzt werden.

+0

+1 Das klingt plausibel - obwohl ich mir nicht sicher bin, warum die Ergebnisse zwischen .Net-Versionen abweichen würden. Aber wenn * NaNs in den Daten sein können (und das OP sagt, dass es möglich ist), dann wird dies definitiv die Art von Problem verursachen, die beobachtet wurde. –

+0

Das macht Sinn, bitte erlauben Sie mir, diesen Thread für eine Weile zu halten und als Antwort später zu markieren. Ich danke dir sehr. – Howard

+2

@MatthewWatson - vielleicht führt die Funktion 'Sort' in der neuen Version keine unnötigen Vergleiche durch und kann daher keine Inkonsistenzen erkennen. – Henrik

0

Ein wahrscheinlicher Grund ist, dass Ihre Informationen tatsächlich während des Vergleichs geändert werden.

Wenn Sie die Sortierung in einem Hintergrundthread durchführen, erhalten Sie diesen Fehler, wenn der Vergleich bei zweimaliger Abfrage unterschiedliche Werte für denselben Eintrag erhält.

Wenn Ihr Haupt-Thread einen der Werte aktualisiert (z. B. durch Datenbindung), während der Vergleich beispielsweise ausgeführt wird.

Stellen Sie sicher, dass Sie den Wert im Cache zwischenspeichern, sodass Sie immer konsistente Ergebnisse erhalten. Oder akzeptieren Sie, dass der Fehler von Zeit zu Zeit auftreten und wiederholen Sie die Sortierung, wenn dies der Fall ist.

Dies erklärt auch Ihr Gefühl der Abhängigkeit von Maschine/Betriebssystem. Multithreading-Probleme treten je nach Software- und Hardwareunterschieden unterschiedlich auf.